<!DOCTYPE html>
<html lang="zh-CN">





<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/michuanblog/img/favicon.png">
  <link rel="icon" type="image/png" href="/michuanblog/img/favicon.png">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="description" content="Coding">
  <meta name="author" content="胡晗">
  <meta name="keywords" content="">
  <title>面试基础知识 - 胡晗&#39;s Blog</title>

  <link  rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/css/bootstrap.min.css" />


  <link  rel="stylesheet" href="https://cdn.staticfile.org/github-markdown-css/4.0.0/github-markdown.min.css" />
  <link  rel="stylesheet" href="/michuanblog/lib/hint/hint.min.css" />

  
    <link  rel="stylesheet" href="https://cdn.staticfile.org/highlight.js/10.0.0/styles/github-gist.min.css" />
  

  


<!-- 主题依赖的图标库，不要自行修改 -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_yg9cfy8wd6.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_pjno9b9zyxs.css">


<link  rel="stylesheet" href="/michuanblog/css/main.css" />

<!-- 自定义样式保持在最底部 -->


  <script  src="/michuanblog/js/utils.js" ></script>
<meta name="generator" content="Hexo 4.2.1"></head>


<body>
  <header style="height: 70vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand"
       href="/michuanblog/">&nbsp;<strong>MiChuan</strong>&nbsp;</a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/michuanblog/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/michuanblog/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/michuanblog/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/michuanblog/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/michuanblog/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" data-toggle="modal" data-target="#modalSearch">&nbsp;&nbsp;<i
                class="iconfont icon-search"></i>&nbsp;&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="view intro-2" id="background" parallax=true
         style="background: url('/michuanblog/img/default.png') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="container text-center white-text fadeInUp">
            <span class="h2" id="subtitle">
              
            </span>

            
              
  <div class="mt-3 post-meta">
    <i class="iconfont icon-date-fill" aria-hidden="true"></i>
    <time datetime="2020-08-13 15:56">
      2020年8月13日 下午
    </time>
  </div>


<div class="mt-1">
  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      12.9k 字
    </span>
  

  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      154
       分钟
    </span>
  

  
  
</div>

            
          </div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid">
  <div class="row">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-md">
      <div class="container nopadding-md" id="board-ctn">
        <div class="py-5" id="board">
          <div class="post-content mx-auto" id="post">
            
            <article class="markdown-body">
              <h2 id="面试考点"><a href="#面试考点" class="headerlink" title="面试考点"></a>面试考点</h2><p><img src="http://mi_chuan.gitee.io/blog/面试考点.png" srcset="/michuanblog/img/loading.gif" alt=""></p>
<h2 id="操作系统"><a href="#操作系统" class="headerlink" title="操作系统"></a>操作系统</h2><h3 id="死锁"><a href="#死锁" class="headerlink" title="死锁"></a>死锁</h3><h4 id="规范定义"><a href="#规范定义" class="headerlink" title="规范定义"></a>规范定义</h4><p>如果一个进程集合中的每个进程都在等待只能由该进程集合中的其他进程才能引发的事件，那么，该进程集合就是死锁的。</p>
<h4 id="资源死锁的条件"><a href="#资源死锁的条件" class="headerlink" title="资源死锁的条件"></a>资源死锁的条件</h4><ul>
<li>互斥</li>
<li>占用并等待</li>
<li>不可抢占</li>
<li>环路等待</li>
</ul>
<h4 id="解决死锁"><a href="#解决死锁" class="headerlink" title="解决死锁"></a>解决死锁</h4><ul>
<li>死锁检测和恢复</li>
<li>死锁避免：银行家算法</li>
<li>死锁预防：破坏四个条件</li>
</ul>
<h3 id="进程"><a href="#进程" class="headerlink" title="进程"></a>进程</h3><h4 id="定义"><a href="#定义" class="headerlink" title="定义"></a>定义</h4><p>在进程模型中，计算机上所有可运行的软件，通常也包括操作系统，被组织成若干顺序进程。一个进程就是一个正在执行程序的实例，包括程序计数器、寄存器和变量的当前值。</p>
<h4 id="进程表"><a href="#进程表" class="headerlink" title="进程表"></a>进程表</h4><p>一个进程有关的所有信息，除了该进程自身地址空间的内容以外，均存放在操作系统的一张表中，称为进程表（process table），进程表是数组（或链表）结构，当前存在的每个进程都要占用其中一项。</p>
<p><img src="http://mi_chuan.gitee.io/blog/进程表.png" srcset="/michuanblog/img/loading.gif" alt="进程表"> </p>
<p><img src="http://mi_chuan.gitee.io/blog/中断过程.png" srcset="/michuanblog/img/loading.gif" alt="中断过程"> </p>
<h4 id="进程的创建"><a href="#进程的创建" class="headerlink" title="进程的创建"></a>进程的创建</h4><p>①系统初始化</p>
<p>②执行创建进程的系统调用</p>
<p>③用户请求创建新进程</p>
<p>④批处理作业初始化</p>
<h4 id="进程的状态"><a href="#进程的状态" class="headerlink" title="进程的状态"></a>进程的状态</h4><ul>
<li>运行</li>
<li>就绪</li>
<li>阻塞</li>
</ul>
<p><img src="http://mi_chuan.gitee.io/blog/进程状态.png" srcset="/michuanblog/img/loading.gif" alt="进程状态"> </p>
<h4 id="进程调度"><a href="#进程调度" class="headerlink" title="进程调度"></a>进程调度</h4><h5 id="批处理系统"><a href="#批处理系统" class="headerlink" title="批处理系统"></a>批处理系统</h5><ul>
<li>先来先服务</li>
<li>最短作业优先</li>
<li>最短剩余时间优先</li>
<li>最高响应比优先</li>
</ul>
<h5 id="交互式系统"><a href="#交互式系统" class="headerlink" title="交互式系统"></a>交互式系统</h5><ul>
<li>时间片轮转</li>
<li>优先级调度算法</li>
<li>多级反馈队列调度</li>
</ul>
<h4 id="僵尸进程"><a href="#僵尸进程" class="headerlink" title="僵尸进程"></a>僵尸进程</h4><p>一个子进程结束后，它的父进程并没有等待它（调用wait或者waitpid），那么这个子进程将成为一个僵尸进程。僵尸进程是一个已经死亡的进程，但是并没有真正被销毁。它已经放弃了几乎所有内存空间，没有任何可执行代码，也不能被调度，仅仅在进程表中保留一个位置，记载该进程的进程ID、终止状态以及资源利用信息(CPU时间，内存使用量等等)供父进程收集，除此之外，僵尸进程不再占有任何内存空间。这个僵尸进程可能会一直留在系统中直到系统重启。</p>
<p>危害：占用进程号，而系统所能使用的进程号是有限的；占用内存。</p>
<h4 id="孤儿进程"><a href="#孤儿进程" class="headerlink" title="孤儿进程"></a>孤儿进程</h4><p>一个父进程已经结束了，但是它的子进程还在运行，那么这些子进程将成为孤儿进程。孤儿进程会被Init（进程ID为1）接管，当这些孤儿进程结束时由Init完成状态收集工作。</p>
<h4 id="系统调用"><a href="#系统调用" class="headerlink" title="系统调用"></a>系统调用</h4><ul>
<li>进程管理：fork、exec、exit、waitpid</li>
<li>文件管理：open、close、read、write、lseek、stat</li>
<li>目录和文件：mkdir、rmdir、link、unlink、mount、unmount</li>
<li>杂项：chmod、chdir、kill、time</li>
</ul>
<h3 id="线程"><a href="#线程" class="headerlink" title="线程"></a>线程</h3><h4 id="线程内容和系统调用"><a href="#线程内容和系统调用" class="headerlink" title="线程内容和系统调用"></a>线程内容和系统调用</h4><p><img src="http://mi_chuan.gitee.io/blog/进程和线程内容.png" srcset="/michuanblog/img/loading.gif" alt="进程和线程内容"> </p>
<p><img src="http://mi_chuan.gitee.io/blog/pthread系统调用.png" srcset="/michuanblog/img/loading.gif" alt="pthread系统调用"> </p>
<h4 id="线程间通信"><a href="#线程间通信" class="headerlink" title="线程间通信"></a>线程间通信</h4><p>①全局变量（共享内存）：多个线程可能更改全局变量，因此全局变量最好声明为volatile</p>
<p>②消息队列。</p>
<h3 id="进程间通信"><a href="#进程间通信" class="headerlink" title="进程间通信"></a>进程间通信</h3><ul>
<li><p>竞争条件：两个以上进程读写共享数据，最后结果取决于进程运行的精确时序。</p>
</li>
<li><p>临界区：对共享内存进行访问的程序片段。</p>
</li>
</ul>
<h4 id="通信方式"><a href="#通信方式" class="headerlink" title="通信方式"></a>通信方式</h4><ul>
<li><p>加锁。</p>
</li>
<li><p>信号量：是一个计数器。信号量用于实现进程间的互斥与同步，而不是用于存储进程间通信数据。</p>
</li>
<li><p>互斥量：只有0和1，简化的信号量。</p>
</li>
<li>消息传递MessageQueue。消息队列，就是一个消息的链表，是一系列保存在内核中消息的列表。用户进程可以向消息队列添加消息，也可以向消息队列读取消息。消息队列与管道通信相比，其优势是对每个消息指定特定的消息类型，接收的时候不需要按照队列次序，而是可以根据自定义条件接收特定类型的消息。</li>
<li>管道FIFO。半双工的（即数据只能在一个方向上流动），具有固定的读端和写端。它只能用于具有亲缘关系的进程之间的通信（也是父子进程或者兄弟进程之间）。它可以看成是一种特殊的文件，对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件，并不属于其他任何文件系统，并且只存在于内存中。管道分为pipe（无名管道）和fifo（命名管道）两种，除了建立、打开、删除的方式不同外，这两种管道几乎是一样的。他们都是通过内核缓冲区实现数据传输。</li>
<li>共享存储SharedMemory。共享内存允许两个或多个进程共享一个给定的存储区，这一段存储区可以被两个或两个以上的进程映射至自身的地址空间中，一个进程写入共享内存的信息，可以被其他使用这个共享内存的进程，通过一个简单的内存读取读出。</li>
<li>信号（signal、kill）。</li>
</ul>
<h3 id="编译过程"><a href="#编译过程" class="headerlink" title="编译过程"></a>编译过程</h3><p><img src="http://mi_chuan.gitee.io/blog/编译链接.png" srcset="/michuanblog/img/loading.gif" alt="编译链接"> </p>
<h3 id="Linux-系统启动过程"><a href="#Linux-系统启动过程" class="headerlink" title="Linux 系统启动过程"></a>Linux 系统启动过程</h3><p>5个阶段</p>
<p><img src="http://mi_chuan.gitee.io/blog/linux启动过程.png" srcset="/michuanblog/img/loading.gif" alt=""></p>
<h4 id="内核引导"><a href="#内核引导" class="headerlink" title="内核引导"></a>内核引导</h4><p>计算机打开电源后，首先是BIOS开机自检，按照BIOS中设置的启动设备（通常是硬盘）来启动。</p>
<p>操作系统接管硬件以后，首先读入 /boot 目录下的内核文件。</p>
<h4 id="运行-init"><a href="#运行-init" class="headerlink" title="运行 init"></a>运行 init</h4><p>init 进程是系统所有进程的起点，你可以把它比拟成系统所有进程的老祖宗，没有这个进程，系统中任何进程都不会启动。</p>
<p>init 程序首先是需要读取配置文件 /etc/inittab。</p>
<h5 id="运行级别"><a href="#运行级别" class="headerlink" title="运行级别"></a>运行级别</h5><p>Linux系统有7个运行级别(runlevel)：</p>
<ul>
<li>运行级别0：系统停机状态，系统默认运行级别不能设为0，否则不能正常启动</li>
<li>运行级别1：单用户工作状态，root权限，用于系统维护，禁止远程登陆</li>
<li>运行级别2：多用户状态(没有NFS)</li>
<li>运行级别3：完全的多用户状态(有NFS)，登陆后进入控制台命令行模式</li>
<li>运行级别4：系统未使用，保留</li>
<li>运行级别5：X11控制台，登陆后进入图形GUI模式</li>
<li>运行级别6：系统正常关闭并重启，默认运行级别不能设为6，否则不能正常启动</li>
</ul>
<h4 id="系统初始化"><a href="#系统初始化" class="headerlink" title="系统初始化"></a>系统初始化</h4><p>在init的配置文件中有这么一行： si::sysinit:/etc/rc.d/rc.sysinit　它调用执行了/etc/rc.d/rc.sysinit，而rc.sysinit是一个bash shell的脚本，它主要是完成一些系统初始化的工作，rc.sysinit是每一个运行级别都要首先运行的重要脚本。</p>
<p>它主要完成的工作有：激活交换分区，检查磁盘，加载硬件模块以及其它一些需要优先执行任务。</p>
<h4 id="建立终端"><a href="#建立终端" class="headerlink" title="建立终端"></a>建立终端</h4><p>rc执行完毕后，返回init。这时基本系统环境已经设置好了，各种守护进程也已经启动了。</p>
<p>init接下来会打开6个终端，以便用户登录系统。</p>
<h4 id="用户登录系统"><a href="#用户登录系统" class="headerlink" title="用户登录系统"></a>用户登录系统</h4><p>登录方式有三种：</p>
<ul>
<li>（1）命令行登录</li>
<li>（2）ssh登录</li>
<li>（3）图形界面登录</li>
</ul>
<h3 id="Linux系统调用"><a href="#Linux系统调用" class="headerlink" title="Linux系统调用"></a>Linux系统调用</h3><h4 id="添加系统调用"><a href="#添加系统调用" class="headerlink" title="添加系统调用"></a>添加系统调用</h4><ol>
<li>下载内核源代码</li>
<li>添加系统调用号</li>
</ol>
<pre><code class="hljs shell">vim ./arch/x86/entry/syscalls/syscall_64.tbl</code></pre>
<pre><code class="hljs basic"><span class="hljs-symbol">334 </span><span class="hljs-number">64</span>  mycopy          sys_mycopy</code></pre>
<ol>
<li>声明系统调用函数原型</li>
</ol>
<pre><code class="hljs shell">vim include/linux/syscalls.h</code></pre>
<pre><code class="hljs C"><span class="hljs-function">asmlinkage <span class="hljs-keyword">long</span> <span class="hljs-title">sys_mycopy</span><span class="hljs-params">(<span class="hljs-keyword">const</span> <span class="hljs-keyword">char</span> __user *target, <span class="hljs-keyword">const</span> <span class="hljs-keyword">char</span> __user *source)</span></span>;</code></pre>
<ol>
<li>添加系统调用函数的定义</li>
</ol>
<pre><code class="hljs shell">vim kernel/sys.c</code></pre>
<pre><code class="hljs avrasm"><span class="hljs-symbol">get_ds:</span> 获得kernel的内存访问地址范围
<span class="hljs-symbol">get_fs:</span> 取得当前的地址访问限制值
<span class="hljs-symbol">set_fs:</span> 设置当前的地址访问限制值</code></pre>
<pre><code class="hljs C">SYSCALL_DEFINE2(mycopy, <span class="hljs-keyword">const</span> <span class="hljs-keyword">char</span> __user *, _target, <span class="hljs-keyword">const</span> <span class="hljs-keyword">char</span> __user *, _source)&#123;
    <span class="hljs-keyword">char</span> *target;
    <span class="hljs-keyword">char</span> *source;
    <span class="hljs-keyword">char</span> buf[<span class="hljs-number">512</span>]; 
	<span class="hljs-keyword">int</span> sor_fd, tar_fd, Readsum, WriteRes;
	
	<span class="hljs-comment">//get point</span>
	target = strndup_user(_target,PAGE_SIZE);
	<span class="hljs-keyword">if</span>(IS_ERR(target))&#123;
	    printk(<span class="hljs-string">"point error!\n"</span>);
	    <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
	&#125;
	
	source = strndup_user(_source,PAGE_SIZE);
	<span class="hljs-keyword">if</span>(IS_ERR(source))&#123;
	    printk(<span class="hljs-string">"point error!\n"</span>);
	    <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
	&#125;

	<span class="hljs-comment">// kernel -&gt; User space    --&gt;  fs</span>
	<span class="hljs-keyword">mm_segment_t</span> fs;
	fs = get_fs();  <span class="hljs-comment">//get access restriction value</span>
	set_fs(get_ds());  <span class="hljs-comment">//set kernel restriction value</span>

	<span class="hljs-comment">// open file</span>
	sor_fd = sys_open(source, O_RDONLY, S_IRUSR);
	<span class="hljs-keyword">if</span> (sor_fd == <span class="hljs-number">-1</span>)
	&#123;
		printk(<span class="hljs-string">"copy: open %s error\n"</span>, source);
		set_fs(fs);   <span class="hljs-comment">//recovery</span>
		<span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
	&#125;

	tar_fd = sys_open(target, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
	<span class="hljs-keyword">if</span> (tar_fd == <span class="hljs-number">-1</span>)
	&#123;
		printk(<span class="hljs-string">"copy: create %s error\n"</span>, target);
		set_fs(fs);   <span class="hljs-comment">//recovery</span>
		<span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
	&#125;
	printk(<span class="hljs-string">"open file success\n"</span>);

	<span class="hljs-keyword">while</span> (<span class="hljs-number">1</span>)
	&#123;
		Readsum = sys_read(sor_fd, buf, <span class="hljs-number">512</span>);
		<span class="hljs-keyword">if</span> (Readsum == <span class="hljs-number">-1</span>)
		&#123;
			printk(<span class="hljs-string">"copy: read %s error\n"</span>, source);
			set_fs(fs);   <span class="hljs-comment">//recovery</span>
			<span class="hljs-keyword">return</span> <span class="hljs-number">-2</span>;
		&#125;
		<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Readsum &gt; <span class="hljs-number">0</span>)
		&#123;
			WriteRes = sys_write(tar_fd, buf, Readsum);
			<span class="hljs-keyword">if</span> (WriteRes != Readsum)
			&#123;
				printk(<span class="hljs-string">"copy: write %s error\n"</span>, target);
				set_fs(fs);   <span class="hljs-comment">//recovery</span>
				<span class="hljs-keyword">return</span> <span class="hljs-number">-2</span>;
			&#125;
		&#125;
		<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Readsum == <span class="hljs-number">0</span>)
		&#123;
			printk(<span class="hljs-string">"copy: copy %s complete\n"</span>, source);
			<span class="hljs-keyword">break</span>;
		&#125;
	&#125;

	<span class="hljs-comment">// close file</span>
	sys_close(tar_fd);
	sys_close(sor_fd);
	set_fs(fs);   <span class="hljs-comment">//recovery</span>

	<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;</code></pre>
<p>调用 sys_open,sys_read,sys_write 函数时，为保护内核空间，会首先 </p>
<p>对参数进行检查，为防止发生段错误，需要通过设置 set_fs(KERNEL_DS)将其能 </p>
<p>访问的空间限制扩大到内核空间，在完成内核函数调用返回用户空间时，需恢复 </p>
<p>成原来的访问范围： </p>
<pre><code class="hljs C"><span class="hljs-keyword">mm_segment_t</span> fs; 

fs = get_fs(); <span class="hljs-comment">//get access restriction value </span>

set_fs(get_ds()); <span class="hljs-comment">//set kernel restriction value </span>

<span class="hljs-comment">// close file </span>

sys_close(tar_fd); 

sys_close(sor_fd);

set_fs(fs); <span class="hljs-comment">//recovery</span></code></pre>
<ol>
<li>编译内核</li>
<li>将生成的内核文件(arch/x86_64/boot/bzImage)，复制进/boot中</li>
<li>添加引导到grub</li>
<li>重启，选择进入新的内核</li>
<li>测试系统调用</li>
</ol>
<h4 id="进程控制"><a href="#进程控制" class="headerlink" title="进程控制"></a>进程控制</h4><div class="table-container">
<table>
<thead>
<tr>
<th>函数名</th>
<th>描述</th>
<th>文件</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>fork</strong></td>
<td>创建一个新进程</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/kernel/fork.c" target="_blank" rel="noopener">kernel/fork.c</a></td>
</tr>
<tr>
<td><strong>clone</strong></td>
<td>按指定条件创建子进程</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/kernel/fork.c" target="_blank" rel="noopener">kernel/fork.c</a></td>
</tr>
<tr>
<td><strong>execve</strong></td>
<td>运行可执行文件</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/exec.c" target="_blank" rel="noopener">fs/exec.c</a></td>
</tr>
<tr>
<td><strong>exit</strong></td>
<td>中止进程</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/kernel/exit.c" target="_blank" rel="noopener">kernel/exit.c</a></td>
</tr>
<tr>
<td><strong>getpid</strong></td>
<td>获取进程标识号</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/kernel/sys.c" target="_blank" rel="noopener">kernel/sys.c</a></td>
</tr>
<tr>
<td><strong>pause</strong></td>
<td>挂起进程，等待信号</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/kernel/signal.c" target="_blank" rel="noopener">kernel/signal.c</a></td>
</tr>
<tr>
<td><strong>vfork</strong></td>
<td>创建一个子进程，以供执行新程序，常与execve等同时使用</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/kernel/fork.c" target="_blank" rel="noopener">kernel/fork.c</a></td>
</tr>
<tr>
<td><strong>wait</strong></td>
<td>等待子进程终止</td>
<td></td>
</tr>
<tr>
<td><strong>waitpid</strong></td>
<td>等待指定子进程终止</td>
</tr>
</tbody>
</table>
</div>
<h4 id="文件系统控制"><a href="#文件系统控制" class="headerlink" title="文件系统控制"></a>文件系统控制</h4><div class="table-container">
<table>
<thead>
<tr>
<th>函数名</th>
<th>描述</th>
<th>文件</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>open</strong></td>
<td>打开文件</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/open.c" target="_blank" rel="noopener">fs/open.c</a></td>
</tr>
<tr>
<td><strong>creat</strong></td>
<td>创建新文件</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/open.c" target="_blank" rel="noopener">fs/open.c</a></td>
</tr>
<tr>
<td><strong>close</strong></td>
<td>关闭文件描述字</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/open.c" target="_blank" rel="noopener">fs/open.c</a></td>
</tr>
<tr>
<td><strong>read</strong></td>
<td>读文件</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/read_write.c" target="_blank" rel="noopener">fs/read_write.c</a></td>
</tr>
<tr>
<td><strong>write</strong></td>
<td>写文件</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/read_write.c" target="_blank" rel="noopener">fs/read_write.c</a></td>
</tr>
<tr>
<td><strong>lseek</strong></td>
<td>移动文件指针</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/read_write.c" target="_blank" rel="noopener">fs/read_write.c</a></td>
</tr>
<tr>
<td><strong>chdir</strong></td>
<td>改变当前工作目录</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/open.c" target="_blank" rel="noopener">fs/open.c</a></td>
</tr>
<tr>
<td><strong>chmod</strong></td>
<td>改变文件方式</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/open.c" target="_blank" rel="noopener">fs/open.c</a></td>
</tr>
<tr>
<td><strong>chown</strong></td>
<td>改变文件的属主或用户组</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/open.c" target="_blank" rel="noopener">fs/open.c</a></td>
</tr>
<tr>
<td><strong>stat</strong></td>
<td>取文件状态信息</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/stat.c" target="_blank" rel="noopener">fs/stat.c</a></td>
</tr>
<tr>
<td><strong>mkdir</strong></td>
<td>创建目录</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/namei.c" target="_blank" rel="noopener">fs/namei.c</a></td>
</tr>
<tr>
<td><strong>link</strong></td>
<td>创建链接</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/namei.c" target="_blank" rel="noopener">fs/namei.c</a></td>
</tr>
<tr>
<td><strong>symlink</strong></td>
<td>创建符号链接</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/namei.c" target="_blank" rel="noopener">fs/namei.c</a></td>
</tr>
<tr>
<td><strong>unlink</strong></td>
<td>删除链接</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/namei.c" target="_blank" rel="noopener">fs/namei.c</a></td>
</tr>
<tr>
<td><strong>mount</strong></td>
<td>安装文件系统</td>
<td><a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/namespace.c" target="_blank" rel="noopener">fs/namespace.c</a></td>
</tr>
<tr>
<td><strong>umount</strong></td>
<td>卸下文件系统</td>
</tr>
</tbody>
</table>
</div>
<h3 id="IO多路复用"><a href="#IO多路复用" class="headerlink" title="IO多路复用"></a>IO多路复用</h3><h4 id="同步IO"><a href="#同步IO" class="headerlink" title="同步IO"></a>同步IO</h4><p>一个进程可以监视多个描述符，一旦某个描述符就绪（一般是读就绪或者写就绪），能够通知程序进行相应的读写操作。需要在读写事件就绪后自己负责进行读写，也就是说这个读写过程是阻塞的。</p>
<h4 id="异步I-O"><a href="#异步I-O" class="headerlink" title="异步I/O"></a>异步I/O</h4><p>无需自己负责进行读写，异步I/O的实现会负责把数据从内核拷贝到用户空间。</p>
<h4 id="select"><a href="#select" class="headerlink" title="select"></a>select</h4><ol>
<li>select最大的缺陷就是单个进程所打开的FD是有一定限制的，它由FD_SETSIZE设置，默认值是1024<strong>。</strong></li>
<li>对socket进行扫描时是线性扫描，即采用轮询的方法，效率较低。</li>
<li>需要维护一个用来存放大量fd的数据结构，这样会使得用户空间和内核空间在传递该结构时复制开销大。</li>
</ol>
<h4 id="poll"><a href="#poll" class="headerlink" title="poll"></a>poll</h4><p>没有最大连接数的限制，原因是它是基于链表来存储的</p>
<h4 id="epoll"><a href="#epoll" class="headerlink" title="epoll"></a>epoll</h4><p>epoll使用“事件”的就绪通知方式，通过epoll_ctl注册fd，一旦该fd就绪，内核就会采用类似callback的回调机制来激活该fd，epoll_wait便可以收到通知。</p>
<h3 id="Linux常用命令"><a href="#Linux常用命令" class="headerlink" title="Linux常用命令"></a>Linux常用命令</h3><h4 id="开关机与用户切换"><a href="#开关机与用户切换" class="headerlink" title="开关机与用户切换"></a>开关机与用户切换</h4><div class="table-container">
<table>
<thead>
<tr>
<th>命令</th>
<th>功能</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>shutdown –h now</strong></td>
<td>立刻进行关机</td>
</tr>
<tr>
<td><strong>shutdown –r now</strong></td>
<td>现在重新启动计算机</td>
</tr>
<tr>
<td><strong>reboot</strong></td>
<td>现在重新启动计算机</td>
</tr>
<tr>
<td><strong>su</strong></td>
<td>切换用户</td>
</tr>
<tr>
<td><strong>passwd</strong></td>
<td>修改用户密码</td>
</tr>
<tr>
<td><strong>logout</strong></td>
<td>用户注销</td>
</tr>
</tbody>
</table>
</div>
<h4 id="快捷命令"><a href="#快捷命令" class="headerlink" title="快捷命令"></a>快捷命令</h4><div class="table-container">
<table>
<thead>
<tr>
<th>命令</th>
<th>功能</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>tab</strong></td>
<td>命令补全</td>
</tr>
<tr>
<td><strong>clear</strong></td>
<td>清屏</td>
</tr>
<tr>
<td><strong>history</strong></td>
<td>查找历史命令</td>
</tr>
<tr>
<td><strong>ctrl+k</strong></td>
<td>删除此处至末尾所有内容</td>
</tr>
<tr>
<td><strong>ctrl+u</strong></td>
<td>删除此处至开始所有内容</td>
</tr>
<tr>
<td><strong>ctrl+w</strong></td>
<td>清除当前行</td>
</tr>
<tr>
<td><strong>ctrl+l</strong></td>
<td>清屏</td>
</tr>
<tr>
<td><strong>ctrl+a</strong></td>
<td>光标跳到开头</td>
</tr>
<tr>
<td><strong>ctrl+e</strong></td>
<td>光标跳到结尾</td>
</tr>
<tr>
<td><strong>ctrl+左右箭头</strong></td>
<td>向左/右移动一个单词</td>
</tr>
</tbody>
</table>
</div>
<h4 id="常用工具命令"><a href="#常用工具命令" class="headerlink" title="常用工具命令"></a>常用工具命令</h4><div class="table-container">
<table>
<thead>
<tr>
<th>命令</th>
<th>功能</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>wc</strong></td>
<td>文本统计</td>
</tr>
<tr>
<td><strong>du</strong></td>
<td>文件大小统计</td>
</tr>
<tr>
<td><strong>find</strong></td>
<td>文件检索命令</td>
</tr>
</tbody>
</table>
</div>
<h4 id="常用目录-文件操作命令"><a href="#常用目录-文件操作命令" class="headerlink" title="常用目录/文件操作命令"></a>常用目录/文件操作命令</h4><div class="table-container">
<table>
<thead>
<tr>
<th>命令</th>
<th>功能</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>ls -a</strong></td>
<td>展示当前目录下所有的文件</td>
</tr>
<tr>
<td><strong>ll</strong></td>
<td>展示当前目录下文件的详细信息</td>
</tr>
<tr>
<td><strong>ll -h</strong></td>
<td>友好的显示当前目录下文件的详细信息</td>
</tr>
<tr>
<td><strong>pwd</strong></td>
<td>显示目前的目录</td>
</tr>
<tr>
<td><strong>chmod u=rwx,g=rw,o=r aaa.txt</strong></td>
<td>修改文件/目录的权限</td>
</tr>
<tr>
<td><strong>chmod ug+x test1.txt</strong></td>
<td>修改文件/目录的权限</td>
</tr>
<tr>
<td><strong>nl</strong></td>
<td>带行号显示文件内容</td>
</tr>
<tr>
<td><strong>less</strong></td>
<td>按页显示文件内容</td>
</tr>
</tbody>
</table>
</div>
<h4 id="系统常用操作命令"><a href="#系统常用操作命令" class="headerlink" title="系统常用操作命令"></a>系统常用操作命令</h4><div class="table-container">
<table>
<thead>
<tr>
<th>命令</th>
<th>功能</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>ifconfig</strong></td>
<td>显示ip</td>
</tr>
<tr>
<td><strong>kill -9 pid</strong></td>
<td>杀死某个进程</td>
</tr>
<tr>
<td><strong>ps</strong></td>
<td>查当前进程</td>
</tr>
<tr>
<td><strong>netstat</strong> [-a,-t,-u,-n,-l,-p]</td>
<td>查看端口开放情况</td>
</tr>
<tr>
<td><strong>df -h</strong></td>
<td>查看磁盘分区</td>
</tr>
</tbody>
</table>
</div>
<h2 id="计算机网络"><a href="#计算机网络" class="headerlink" title="计算机网络"></a>计算机网络</h2><h3 id="可靠数据传输"><a href="#可靠数据传输" class="headerlink" title="可靠数据传输"></a>可靠数据传输</h3><h4 id="SW3"><a href="#SW3" class="headerlink" title="SW3"></a>SW3</h4><p>超时重传、序号、确认号、差错检测</p>
<h4 id="GBN（回退N步）"><a href="#GBN（回退N步）" class="headerlink" title="GBN（回退N步）"></a>GBN（回退N步）</h4><p>累积确认、序号、校验和、超时重传</p>
<p><img src="http://mi_chuan.gitee.io/blog/GBN.png" srcset="/michuanblog/img/loading.gif" alt="img"> </p>
<p><img src="http://mi_chuan.gitee.io/blog/GBN2.png" srcset="/michuanblog/img/loading.gif" alt="img"> </p>
<p><img src="http://mi_chuan.gitee.io/blog/GBN3.png" srcset="/michuanblog/img/loading.gif" alt="img"> </p>
<h4 id="SR（选择重传）"><a href="#SR（选择重传）" class="headerlink" title="SR（选择重传）"></a>SR（选择重传）</h4><p><img src="http://mi_chuan.gitee.io/blog/SR1.png" srcset="/michuanblog/img/loading.gif" alt="img"> </p>
<p><img src="http://mi_chuan.gitee.io/blog/SR2.png" srcset="/michuanblog/img/loading.gif" alt="img"> </p>
<h3 id="TCP"><a href="#TCP" class="headerlink" title="TCP"></a>TCP</h3><ul>
<li><p>面向连接的点对点传输，可靠传输。</p>
</li>
<li><p>最大报文段长度（MSS）取决于最大传输单元（MTU）（1500字节）：TCP首部40字节，所以MSS为1460字节。</p>
</li>
</ul>
<h4 id="三次握手"><a href="#三次握手" class="headerlink" title="三次握手"></a>三次握手</h4><p>①第一步：客户端的TCP首先向服务器端的TCP发送一个特殊的TCP报文段。该报文段不包含应用层数据。报文段首部标志位SYN=1，报文段称为SYN报文段。客户端随机地选择一个初始序号（client_isn）。报文段封装到一个IP数据报发送到服务器。</p>
<p>②第二步：TCP SYN报文段的IP数据报到达服务器主机，服务器为该TCP连接分配TCP缓存和变量，并向该客户TCP发送允许连接的报文段，这个报文段也不包含应用层数据。首先，SYN=1。其次，首部的确认号字段被置为client _ isn + 1。最后，服务器选择自己的初始序号 （server_isn）。该允许连接的报文段被称为SYNACK报文段（SYNACK segment）。</p>
<p>③第三步：收到SYNACK报文段后，客户也要给该连接分配缓存和变量。客户主机则向服务器发送另外一个报文段；这最后一个报文段对服务器的允许连接的报文段进行了确认，TCP报文段首部的确认字段server_isn + 1，SYN=0。三次握手的第三个阶段可以在报文段负载中携带客户到服务器的数据。</p>
<p><img src="http://mi_chuan.gitee.io/blog/三次握手.png" srcset="/michuanblog/img/loading.gif" alt="img"> </p>
<h4 id="四次挥手"><a href="#四次挥手" class="headerlink" title="四次挥手"></a>四次挥手</h4><p>客户应用进程发出一个关闭连接命令。客户TCP向服务器进程发送一个特殊的TCP报文段，首部中的一个标志位即FIN=l。当服务器接收到该报文段后，就向发送方回送一个确认报文段。然后，服务器发送它自己的终止报文段，其FIN=1。最后，该客户对这个服务器的终止报文段进行确认。</p>
<p><img src="http://mi_chuan.gitee.io/blog/四次挥手.png" srcset="/michuanblog/img/loading.gif" alt="img"></p>
<h4 id="TCP报文段结构"><a href="#TCP报文段结构" class="headerlink" title="TCP报文段结构"></a>TCP报文段结构</h4><p>TCP首部20字节，UDP首部8字节。</p>
<p><img src="http://mi_chuan.gitee.io/blog/TCP报文段结构.png" srcset="/michuanblog/img/loading.gif" alt="img"> </p>
<h4 id="可靠性数据传输"><a href="#可靠性数据传输" class="headerlink" title="可靠性数据传输"></a>可靠性数据传输</h4><p>①累积确认，发送方仅维持已发送但未确认最小序号（SendBase）和下一个发送序号（NextSeqNum）。</p>
<p>②接收方缓存失序报文。</p>
<p>③冗余ACK，快速重传。</p>
<p>④超时事件。</p>
<h4 id="流量控制"><a href="#流量控制" class="headerlink" title="流量控制"></a>流量控制</h4><p>发送方维护一个接收窗口，接收方通过指示其大小说明还有多少缓存空间。</p>
<ul>
<li><p>LastByteRead：主机B上的应用进程从缓存读出的数据流的最后一个字节的编号。</p>
</li>
<li><p>LastByteRcvd：从网络中到达的并且已放入主机B接收缓存中的数据流的最后一个字节的编号。</p>
</li>
</ul>
<p>TCP不允许已分配的缓存溢出，下式必须成立：</p>
<script type="math/tex; mode=display">
LastByteRcvd-LastByteRead = RevBuffer</script><p>接收窗口用rwnd表示，根据缓存可用空间的数量来设置：</p>
<script type="math/tex; mode=display">
rwnd=RevBuffer-[LastByteRevd-LastByteRead]</script><p>当主机B的接收窗口为0时，主机A继续发送只有一个字节数据的报文段。这些报文段将会被接收方确认。最终缓存将开始清空，并且确认报文里将包含一个非0的rwnd值。</p>
<h4 id="拥塞控制（加性增、乘性减）"><a href="#拥塞控制（加性增、乘性减）" class="headerlink" title="拥塞控制（加性增、乘性减）"></a>拥塞控制（加性增、乘性减）</h4><h5 id="拥塞原因"><a href="#拥塞原因" class="headerlink" title="拥塞原因"></a>拥塞原因</h5><p>①多跳路径</p>
<p>②路由器有限缓存</p>
<p>③排队时延、处理时延、传输时延</p>
<h5 id="拥塞控制方法"><a href="#拥塞控制方法" class="headerlink" title="拥塞控制方法"></a>拥塞控制方法</h5><p>拥塞窗口表示为cwnd，它对一个TCP发送方能向网络中发送流量的速率进行了限制。</p>
<p>①慢启动：TCP连接开始，cwnd的值通常初始置为一个MSS的较小值。发送速率起始慢，但在慢启动阶段以指数增长。</p>
<p>②拥塞避免：当到达或超过ssthresh的值时，每个RTT只将cwnd的值增加一个MSS，进入线性增长阶段。</p>
<p>③超时指示的丢包：TCP发送方将ssthresh（“慢启动阀值”）设置为cwnd/2，即ssthresh置为拥塞窗口值的一半。将cwnd设置为l并重新开始慢启动过程。</p>
<p>④3个冗余ACK指示丢包：TCP发送方将cwnd的值减半再加上3个MSS，将ssthresh的值记录为原cwnd的值的一半。接下来进入快速恢复状态。</p>
<h3 id="UDP"><a href="#UDP" class="headerlink" title="UDP"></a>UDP</h3><p>（1）无连接，不可靠，尽力而为的交付服务。</p>
<p>（2）用于丢包容忍率高，低时延的场合。</p>
<p><img src="http://mi_chuan.gitee.io/blog/UDP应用.png" srcset="/michuanblog/img/loading.gif" alt="img"> </p>
<p>（3）UDP报文段结构</p>
<p><img src="http://mi_chuan.gitee.io/blog/UDP报文段结构.png" srcset="/michuanblog/img/loading.gif" alt="img"> </p>
<h3 id="Socket"><a href="#Socket" class="headerlink" title="Socket"></a>Socket</h3><h4 id="类型"><a href="#类型" class="headerlink" title="类型"></a>类型</h4><ul>
<li><p>流类型（Stream Sockets）。</p>
<p>流式套接字提供了一种可靠的、面向连接的数据传输方法，使用传输控制协议TCP。</p>
</li>
<li><p>数据报类型（Datagram Sockets）。</p>
<p>数据报套接字提供了一种不可靠的、非连接的数据包传输方式，使用用户数据报协议UDP。</p>
</li>
</ul>
<h4 id="I-O模式"><a href="#I-O模式" class="headerlink" title="I/O模式"></a>I/O模式</h4><ul>
<li><p>阻塞式I/O（blocking I/O）</p>
<p>在阻塞方式下，收发数据的函数在调用后一直要到传送完毕或者出错才能完成，在阻塞期间，除了等待网络操作的完成不能进行任何操作。阻塞式I/O是一个Winsock API函数的缺省行为。</p>
</li>
<li><p>非阻塞式I/O（non-blocking I/O）</p>
<p>对于非阻塞方式，Winsock API函数被调用后立即返回；当网络操作完成后，由Winsock给应用程序发送消息（Socket Notifications）通知操作完成，这时应用程序可以根据发送的消息中的参数对消息做出响应。Winsock提供了2种异步接受数据的方法：一种方法是使用BSD类型的函数select（），另外一种方法是使用Winsock提供的专用函数WSAAsyncSelect（）。</p>
</li>
</ul>
<h4 id="连接流程"><a href="#连接流程" class="headerlink" title="连接流程"></a>连接流程</h4><p><img src="http://mi_chuan.gitee.io/blog/winsocket.png" srcset="/michuanblog/img/loading.gif" alt="socket"></p>
<h3 id="HTTP"><a href="#HTTP" class="headerlink" title="HTTP"></a>HTTP</h3><div class="table-container">
<table>
<thead>
<tr>
<th>版本</th>
<th>内容</th>
</tr>
</thead>
<tbody>
<tr>
<td>HTTP/1.0</td>
<td>传输内容格式不限制，增加PUT、PATCH、HEAD、 OPTIONS、DELETE命令</td>
</tr>
<tr>
<td>HTTP/1.1</td>
<td>持久连接(长连接)、节约带宽、HOST域、管道机制、分块传输编码</td>
</tr>
<tr>
<td>HTTP/2</td>
<td>多路复用、服务器推送、头信息压缩、二进制协议等</td>
</tr>
</tbody>
</table>
</div>
<h4 id="HTTP报文格式"><a href="#HTTP报文格式" class="headerlink" title="HTTP报文格式"></a>HTTP报文格式</h4><p><img src="http://mi_chuan.gitee.io/blog/http报文格式.png" srcset="/michuanblog/img/loading.gif" alt="http报文格式"></p>
<h4 id="HTTP特点"><a href="#HTTP特点" class="headerlink" title="HTTP特点"></a>HTTP特点</h4><ol>
<li>无状态：协议对客户端没有状态存储，对事物处理没有“记忆”能力，比如访问一个网站需要反复进行登录操作</li>
<li>无连接：HTTP/1.1之前，由于无状态特点，每次请求需要通过TCP三次握手四次挥手，和服务器重新建立连接。比如某个客户机在短时间多次请求同一个资源，服务器并不能区别是否已经响应过用户的请求，所以每次需要重新响应请求，需要耗费不必要的时间和流量。</li>
<li>基于请求和响应：基本的特性，由客户端发起请求，服务端响应</li>
<li>简单快速、灵活</li>
<li>通信使用明文、请求和响应不会对通信方进行确认、无法保护数据的完整性</li>
</ol>
<h5 id="针对无状态的一些解决策略"><a href="#针对无状态的一些解决策略" class="headerlink" title="针对无状态的一些解决策略"></a>针对无状态的一些解决策略</h5><ol>
<li>通过Cookie/Session技术</li>
<li>HTTP/1.1持久连接（HTTP keep-alive）方法，只要任意一端没有明确提出断开连接，则保持TCP连接状态，在请求首部字段中的Connection: keep-alive即为表明使用了持久连接</li>
</ol>
<h4 id="HTTPS特点"><a href="#HTTPS特点" class="headerlink" title="HTTPS特点"></a>HTTPS特点</h4><ol>
<li>内容加密：采用混合加密技术，中间者无法直接查看明文内容</li>
<li>验证身份：通过证书认证客户端访问的是自己的服务器</li>
<li>保护数据完整性：防止传输的内容被中间人冒充或者篡改</li>
</ol>
<h4 id="HTTPS和HTTP的区别"><a href="#HTTPS和HTTP的区别" class="headerlink" title="HTTPS和HTTP的区别"></a>HTTPS和HTTP的区别</h4><ol>
<li>HTTPS是加密传输协议，HTTP是明文传输协议</li>
<li>HTTPS需要用到SSL证书，而HTTP不用</li>
<li>HTTPS比HTTP更加安全，对搜索引擎更友好，利于SEO</li>
<li>HTTPS标准端口443，HTTP标准端口80</li>
<li>HTTPS基于传输层，HTTP基于应用层</li>
</ol>
<h4 id="TLS-SSL工作原理"><a href="#TLS-SSL工作原理" class="headerlink" title="TLS/SSL工作原理"></a>TLS/SSL工作原理</h4><p>TLS的基本工作方式是，客户端使用非对称加密与服务器进行通信，实现身份验证并协商对称加密使用的密钥，然后对称加密算法采用协商密钥对信息以及信息摘要进行加密通信，不同的节点之间采用的对称密钥不同，从而可以保证信息只能通信双方获取。</p>
<h4 id="常见状态码"><a href="#常见状态码" class="headerlink" title="常见状态码"></a>常见状态码</h4><div class="table-container">
<table>
<thead>
<tr>
<th>状态码</th>
<th>含义</th>
</tr>
</thead>
<tbody>
<tr>
<td>200 OK</td>
<td>表示从客户端发来的请求在服务器端被正确处理</td>
</tr>
<tr>
<td>301 moved permanently</td>
<td>永久性重定向，表示资源已被分配了新的 URL</td>
</tr>
<tr>
<td>403 forbidden</td>
<td>表示对请求资源的访问被服务器拒绝</td>
</tr>
<tr>
<td>404 not found</td>
<td>表示在服务器上没有找到请求的资源</td>
</tr>
<tr>
<td>500 internal sever error</td>
<td>表示服务器端在执行请求时发生了错误</td>
</tr>
<tr>
<td>501 Not Implemented</td>
<td>服务器不支持请求的功能，无法完成请求</td>
</tr>
<tr>
<td>503 service unavailable</td>
<td>表明服务器暂时处于超负载或正在停机维护，无法处理请求</td>
</tr>
</tbody>
</table>
</div>
<h4 id="Post-和-Get"><a href="#Post-和-Get" class="headerlink" title="Post 和 Get"></a>Post 和 Get</h4><ul>
<li>Get 多用于无副作用，幂等的场景；Post 多用于副作用，不幂等的场景</li>
<li>Get 请求能缓存，Post 不能</li>
<li>Post 相对 Get 安全一点点，因为Get 请求都包含在 URL 里，且会被浏览器保存历史纪录</li>
<li>Post 可以通过 request body来传输比 Get 更多的数据，Get 没有这个技术</li>
<li>Post 支持更多的编码类型且不对数据类型限制</li>
</ul>
<h2 id="C"><a href="#C" class="headerlink" title="C++"></a>C++</h2><h3 id="static关键字"><a href="#static关键字" class="headerlink" title="static关键字"></a>static关键字</h3><h4 id="局部变量"><a href="#局部变量" class="headerlink" title="局部变量"></a>局部变量</h4><p>静态局部变量使用static修饰符定义，即使在声明时未赋初值，编译器也会把它初始化为0。且静态局部变量存储于进程的全局数据区，即使函数返回，它的值也会保持不变。</p>
<p>普通局部变量存储于进程栈空间，使用完毕会立即释放。编译器一般不对普通局部变量进行初始化，也就是说它的值在初始时是不确定的，除非对其显式赋值。</p>
<h4 id="全局变量"><a href="#全局变量" class="headerlink" title="全局变量"></a>全局变量</h4><p>全局变量定义在函数体外部，在全局数据区分配存储空间，且编译器会自动对其初始化。</p>
<p>普通全局变量对整个工程可见，其他文件可以使用extern外部声明后直接使用。也就是说其他文件不能再定义一个与其相同名字的变量了（否则编译器会认为它们是同一个变量）。</p>
<p>静态全局变量仅对当前文件可见，其他文件不可访问，其他文件可以定义与其同名的变量，两者互不影响。</p>
<h4 id="函数"><a href="#函数" class="headerlink" title="函数"></a>函数</h4><p>静态函数只能在声明它的文件中可见，其他文件不能引用该函数。不同的文件可以使用相同名字的静态函数，互不影响。</p>
<h4 id="静态数据成员"><a href="#静态数据成员" class="headerlink" title="静态数据成员"></a>静态数据成员</h4><p>静态数据成员存储在全局数据区，静态数据成员在定义时分配存储空间，所以不能在类声明中定义</p>
<p>静态数据成员是类的成员，无论定义了多少个类的对象，静态数据成员的拷贝只有一个，且对该类的所有对象可见。也就是说任一对象都可以对静态数据成员进行操作。而对于非静态数据成员，每个对象都有自己的一份拷贝。</p>
<p>由于上面的原因，静态数据成员不属于任何对象，在没有类的实例时其作用域就可见，在没有任何对象时，就可以进行操作</p>
<p>和普通数据成员一样，静态数据成员也遵从public, protected, private访问规则</p>
<p>静态数据成员的初始化格式：&lt;数据类型&gt;&lt;类名&gt;::&lt;静态数据成员名&gt;=&lt;值&gt;</p>
<p>类的静态数据成员有两种访问方式：&lt;类对象名&gt;.&lt;静态数据成员名&gt; 或 &lt;类类型名&gt;::&lt;静态数据成员名&gt;</p>
<h4 id="静态成员函数"><a href="#静态成员函数" class="headerlink" title="静态成员函数"></a>静态成员函数</h4><p>静态成员函数没有this指针，它无法访问属于类对象的非静态数据成员，也无法访问非静态成员函数，它只能调用其余的静态成员函数</p>
<p>出现在类体外的函数定义不能指定关键字static</p>
<p>非静态成员函数可以任意地访问静态成员函数和静态数据成员</p>
<h3 id="堆栈"><a href="#堆栈" class="headerlink" title="堆栈"></a>堆栈</h3><h4 id="栈区（stack）"><a href="#栈区（stack）" class="headerlink" title="栈区（stack）"></a>栈区（stack）</h4><p>由编译器自动分配释放 ，存放函数的参数值，局部变量的值等。其操作方式类似于数据结构中的栈。</p>
<h4 id="堆区（heap）"><a href="#堆区（heap）" class="headerlink" title="堆区（heap）"></a>堆区（heap）</h4><p>一般由程序员分配释放， 若程序员不释放，程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事，分配方式倒是类似于链表，呵呵。</p>
<h4 id="全局区（静态区）（static）"><a href="#全局区（静态区）（static）" class="headerlink" title="全局区（静态区）（static）"></a>全局区（静态区）（static）</h4><p>全局变量和静态变量的存储是放在一块的，初始化的全局变量和静态变量在一块区域， 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放</p>
<h4 id="文字常量区"><a href="#文字常量区" class="headerlink" title="文字常量区"></a>文字常量区</h4><p>常量字符串就是放在这里的。 程序结束后由系统释放</p>
<h4 id="程序代码区"><a href="#程序代码区" class="headerlink" title="程序代码区"></a>程序代码区</h4><p>存放函数体的二进制代码。</p>
<h3 id="空类、空结构大小"><a href="#空类、空结构大小" class="headerlink" title="空类、空结构大小"></a>空类、空结构大小</h3><h4 id="空类、空结构大小为1字节"><a href="#空类、空结构大小为1字节" class="headerlink" title="空类、空结构大小为1字节"></a>空类、空结构大小为1字节</h4><pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;stdio.h&gt;</span></span>

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">test1</span>&#123;</span>&#125;;	<span class="hljs-comment">//空结构体</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">test2</span>&#123;</span>&#125;; 	<span class="hljs-comment">//空类</span>
                                                                    
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>
<span class="hljs-function"></span>&#123;
   test1 a;
   test2 b;
   <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"size of empty struct: "</span>&lt;&lt;<span class="hljs-keyword">sizeof</span>(a)&lt;&lt;<span class="hljs-built_in">std</span>::<span class="hljs-built_in">endl</span>;
   <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"size of empty class: "</span>&lt;&lt;<span class="hljs-keyword">sizeof</span>(b)&lt;&lt;<span class="hljs-built_in">std</span>::<span class="hljs-built_in">endl</span>;
   <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;</code></pre>
<h4 id="包含构造函数、析构函数、成员函数类大小为-1字节"><a href="#包含构造函数、析构函数、成员函数类大小为-1字节" class="headerlink" title="包含构造函数、析构函数、成员函数类大小为 1字节"></a>包含构造函数、析构函数、成员函数类大小为 1字节</h4><pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;iostream&gt;    </span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;stdio.h&gt;    </span></span>
    
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">test1</span>&#123;</span>&#125;;<span class="hljs-comment">//空结构    </span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">test2</span>    </span>
<span class="hljs-class">&#123;</span><span class="hljs-comment">//包括构造函数和析构函数的类    </span>
  <span class="hljs-keyword">public</span>:   
  test2()&#123;&#125;;    
  ~test2()&#123;&#125;;    
&#125;;
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">test3</span>&#123;</span><span class="hljs-comment">//包含构造函数和析构函数，成员函数</span>
<span class="hljs-keyword">public</span>:
	test3()&#123;&#125;;
	~test3()&#123;&#125;;
	<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">printt</span><span class="hljs-params">()</span></span>&#123;
		<span class="hljs-built_in">printf</span>(<span class="hljs-string">"."</span>);
	&#125;
&#125;;    
    
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span>    </span>
<span class="hljs-function"></span>&#123;    
  test1 a;    
  test2 b;
  test3 c;    
  <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"空结构体大小： "</span>&lt;&lt;<span class="hljs-keyword">sizeof</span>(a)&lt;&lt;<span class="hljs-built_in">std</span>::<span class="hljs-built_in">endl</span>;    
  <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"空类大小： "</span>&lt;&lt;<span class="hljs-keyword">sizeof</span>(b)&lt;&lt;<span class="hljs-built_in">std</span>::<span class="hljs-built_in">endl</span>;    
  <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"包含构造函数、析构函数、成员函数类大小： "</span>&lt;&lt;<span class="hljs-keyword">sizeof</span>(c)&lt;&lt;<span class="hljs-built_in">std</span>::<span class="hljs-built_in">endl</span>;

  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;    
&#125;</code></pre>
<h4 id="包含构造函数和虚析构函数的类、一个int成员类：一个机器字长"><a href="#包含构造函数和虚析构函数的类、一个int成员类：一个机器字长" class="headerlink" title="包含构造函数和虚析构函数的类、一个int成员类：一个机器字长"></a>包含构造函数和虚析构函数的类、一个int成员类：一个机器字长</h4><pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;iostream&gt;    </span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;stdio.h&gt;    </span></span>
    
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">test1</span>&#123;</span>&#125;;<span class="hljs-comment">//空结构    </span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">test2</span>    </span>
<span class="hljs-class">&#123;</span><span class="hljs-comment">//包含构造函数和虚析构函数的类    </span>
  <span class="hljs-keyword">public</span>:                                                           
  test2()&#123;&#125;;    
  <span class="hljs-keyword">virtual</span> ~test2()&#123;&#125;;
&#125;;
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">test3</span></span>
<span class="hljs-class">&#123;</span>
<span class="hljs-keyword">public</span>:
	test3()&#123;&#125;;
	<span class="hljs-keyword">int</span> a = <span class="hljs-number">0</span>;
&#125;;    
    
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span>    </span>
<span class="hljs-function"></span>&#123;    
  test1 a;    
  test2 b;    
  test3 c;
  <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"空结构体大小："</span>&lt;&lt;<span class="hljs-keyword">sizeof</span>(a)&lt;&lt;<span class="hljs-built_in">std</span>::<span class="hljs-built_in">endl</span>;    
  <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"包含构造函数和虚析构函数的类大小："</span>&lt;&lt;<span class="hljs-keyword">sizeof</span>(b)&lt;&lt;<span class="hljs-built_in">std</span>::<span class="hljs-built_in">endl</span>;   
  <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span>&lt;&lt;<span class="hljs-string">"包含一个int成员："</span>&lt;&lt;<span class="hljs-keyword">sizeof</span>(c)&lt;&lt;<span class="hljs-built_in">std</span>::<span class="hljs-built_in">endl</span>;
  <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;    
&#125;</code></pre>
<h3 id="C-11"><a href="#C-11" class="headerlink" title="C++11"></a>C++11</h3><h4 id="右值引用"><a href="#右值引用" class="headerlink" title="右值引用"></a>右值引用</h4><ul>
<li><p>可以取地址的、有名字的就是左值，反之，不能取地址的、没有名字的就是右值。</p>
</li>
<li><p>右值表示<strong>字面常量、表达式、函数的非引用返回值</strong></p>
</li>
</ul>
<h5 id="左值引用"><a href="#左值引用" class="headerlink" title="左值引用"></a>左值引用</h5><p>“<strong>const 类型 &amp;</strong>”为 “万能”的引用类型，它可以接受非常量左值、常量左值、右值对其进行初始化。</p>
<pre><code class="hljs c++"><span class="hljs-keyword">int</span> &amp;a = <span class="hljs-number">2</span>;       <span class="hljs-comment">// 左值引用绑定到右值，编译失败, err</span>
<span class="hljs-keyword">int</span> b = <span class="hljs-number">2</span>;        <span class="hljs-comment">// 非常量左值</span>
<span class="hljs-keyword">const</span> <span class="hljs-keyword">int</span> &amp;c = b; <span class="hljs-comment">// 常量左值引用绑定到非常量左值，编译通过, ok</span>
<span class="hljs-keyword">const</span> <span class="hljs-keyword">int</span> d = <span class="hljs-number">2</span>;  <span class="hljs-comment">// 常量左值</span>
<span class="hljs-keyword">const</span> <span class="hljs-keyword">int</span> &amp;e = d; <span class="hljs-comment">// 常量左值引用绑定到常量左值，编译通过, ok</span>
<span class="hljs-keyword">const</span> <span class="hljs-keyword">int</span> &amp;b = <span class="hljs-number">2</span>; <span class="hljs-comment">// 常量左值引用绑定到右值，编程通过, ok</span></code></pre>
<h5 id="右值引用-1"><a href="#右值引用-1" class="headerlink" title="右值引用"></a>右值引用</h5><pre><code class="hljs c++"><span class="hljs-keyword">int</span> &amp;&amp; r1 = <span class="hljs-number">22</span>;
<span class="hljs-keyword">int</span> x = <span class="hljs-number">5</span>;
<span class="hljs-keyword">int</span> y = <span class="hljs-number">8</span>;
<span class="hljs-keyword">int</span> &amp;&amp; r2 = x + y;
T &amp;&amp; a = ReturnRvalue();</code></pre>
<p>右值引用是不能够绑定到任何的左值的</p>
<pre><code class="hljs c++"><span class="hljs-keyword">int</span> c;
<span class="hljs-keyword">int</span> &amp;&amp; d = c; <span class="hljs-comment">//err</span></code></pre>
<h4 id="智能指针"><a href="#智能指针" class="headerlink" title="智能指针"></a>智能指针</h4><p><strong>简介：</strong><br>C++ 语言没有自动内存回收机制，程序员每次 new 出来的内存都要手动 delete。程序员忘记 delete，流程太复杂，最终导致没有 delete，异常导致程序过早退出，没有执行 delete 的情况并不罕见。</p>
<p><strong>7 种智能指针：</strong></p>
<h5 id="std-auto-ptr"><a href="#std-auto-ptr" class="headerlink" title="std::auto_ptr"></a>std::auto_ptr</h5><p>std::auto_ptr 可用来管理单个对象的堆内存，但是，请注意如下几点：</p>
<p>（1）尽量不要使用“operator=”。如果使用了，请不要再使用先前对象。<br>（2）记住 release() 函数不会释放对象，仅仅归还所有权。<br>（3）std::auto_ptr 最好不要当成参数传递<br>（4）由于 std::auto_ptr 的“operator=”问题，有其管理的对象不能放入 std::vector 等容器中</p>
<h5 id="boost-scoped-ptr"><a href="#boost-scoped-ptr" class="headerlink" title="boost::scoped_ptr"></a>boost::scoped_ptr</h5><p>（1）独享内存所有权<br>（2）没有 release() 函数<br>（3）不能用于处理指针复制，参数传递<br>（4）管理单个对象的堆内存</p>
<h5 id="boost-shared-ptr"><a href="#boost-shared-ptr" class="headerlink" title="boost::shared_ptr"></a>boost::shared_ptr</h5><p>（1）专门用于共享所有权，由于要共享所有权，在内部使用了引用计数<br>（2）没有 release() 函数<br>（3）提供了一个函数 use_count() ，此函数返回 boost::shared_ptr 内部的引用计数<br>（4）管理单个对象的堆内存</p>
<h5 id="boost-scoped-array"><a href="#boost-scoped-array" class="headerlink" title="boost::scoped_array"></a>boost::scoped_array</h5><p>（1）用于管理动态数组，独享所有权<br>（2）使用内存数组来初始化<br>（3）没有重载 operator*<br>（4）没有 release 函数</p>
<h5 id="boost-shared-array"><a href="#boost-shared-array" class="headerlink" title="boost::shared_array"></a>boost::shared_array</h5><p>（1）内部使用了引用计数<br>（2）使用内存数组来初始化<br>（3）没有重载 operator*</p>
<h5 id="boost-weak-ptr"><a href="#boost-weak-ptr" class="headerlink" title="boost::weak_ptr"></a>boost::weak_ptr</h5><p>boost::weak_ptr 主要用在软件架构设计</p>
<h5 id="boost-intrusive-ptr"><a href="#boost-intrusive-ptr" class="headerlink" title="boost::intrusive_ptr"></a>boost::intrusive_ptr</h5><p>插入式的智能指针，内部不含有引用计数，需要程序员自己加入引用计数</p>
<p><strong>总结</strong></p>
<ul>
<li><p>在可以使用 boost 库的场合下，拒绝使用 std::auto_ptr，因为其不仅不符合 C++ 编程思想，而且极容易出错。</p>
</li>
<li><p>在确定对象无需共享的情况下，使用 boost::scoped_ptr（当然动态数组使用 boost::scoped_array）。</p>
</li>
<li><p>在对象需要共享的情况下，使用 boost::shared_ptr（当然动态数组使用 boost::shared_array）。</p>
</li>
<li><p>在需要访问 boost::shared_ptr 对象，而又不想改变其引用计数的情况下，使用 boost::weak_ptr，一般常用于软件框架设计中。</p>
</li>
<li><p>最后一点，也是要求最苛刻一点：在你的代码中，不要出现 delete 关键字（或 C 语言的 free 函数），因为可以用智能指针去管理。</p>
</li>
</ul>
<h4 id="auto自动类型推导"><a href="#auto自动类型推导" class="headerlink" title="auto自动类型推导"></a>auto自动类型推导</h4><pre><code class="hljs C++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">func</span><span class="hljs-params">(<span class="hljs-keyword">int</span>, <span class="hljs-keyword">int</span>)</span></span>;
auto func2(int, int) -&gt; int;

<span class="hljs-keyword">template</span>&lt;<span class="hljs-keyword">typename</span> T1, <span class="hljs-keyword">typename</span> T2&gt;
auto sum(const T1 &amp; t1, const T2 &amp; t2) -&gt; decltype(t1 + t2)
&#123;
    <span class="hljs-keyword">return</span> t1 + t2;
&#125;

<span class="hljs-keyword">template</span> &lt;<span class="hljs-keyword">typename</span> T1, <span class="hljs-keyword">typename</span> T2&gt;
auto mul(const T1 &amp; t1, const T2 &amp; t2) -&gt; decltype(t1 * t2)
&#123;
    <span class="hljs-keyword">return</span> t1 * t2;
&#125;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">auto</span> a = <span class="hljs-number">3</span>;
    <span class="hljs-keyword">auto</span> b = <span class="hljs-number">4L</span>;
    <span class="hljs-keyword">auto</span> pi = <span class="hljs-number">3.14</span>;

    <span class="hljs-keyword">auto</span> c = mul( sum(a, b), pi );
    <span class="hljs-built_in">cout</span> &lt;&lt; c &lt;&lt; <span class="hljs-built_in">endl</span>;  <span class="hljs-comment">// 21.98</span>

    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;</code></pre>
<pre><code class="hljs C++"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">fun</span><span class="hljs-params">(<span class="hljs-keyword">auto</span> x =<span class="hljs-number">1</span>)</span> </span>&#123;&#125;  <span class="hljs-comment">// 1: auto函数参数，有些编译器无法通过编译</span>

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">str</span></span>
<span class="hljs-class">&#123;</span>
    <span class="hljs-keyword">auto</span> var = <span class="hljs-number">10</span>;   <span class="hljs-comment">// 2: auto非静态成员变量，无法通过编译</span>
&#125;;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">char</span> x[<span class="hljs-number">3</span>];
    <span class="hljs-keyword">auto</span> y = x;
    <span class="hljs-keyword">auto</span> z[<span class="hljs-number">3</span>] = x; <span class="hljs-comment">// 3: auto数组，无法通过编译</span>

    <span class="hljs-comment">// 4: auto模板参数（实例化时），无法通过编译</span>
    <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">auto</span>&gt; x = &#123;<span class="hljs-number">1</span>&#125;;

    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;</code></pre>
<h4 id="decltype"><a href="#decltype" class="headerlink" title="decltype"></a>decltype</h4><pre><code class="hljs C++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;typeinfo&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;vector&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">int</span> i;
    <span class="hljs-keyword">decltype</span>(i) j = <span class="hljs-number">0</span>;
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-keyword">typeid</span>(j).name() &lt;&lt; <span class="hljs-built_in">endl</span>;   <span class="hljs-comment">// 打印出"i", g++表示integer</span>

    <span class="hljs-keyword">float</span> a;
    <span class="hljs-keyword">double</span> b;
    <span class="hljs-keyword">decltype</span>(a + b) c;
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-keyword">typeid</span>(c).name() &lt;&lt; <span class="hljs-built_in">endl</span>;   <span class="hljs-comment">// 打印出"d", g++表示double</span>

    <span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; vec;
    <span class="hljs-function"><span class="hljs-keyword">typedef</span> <span class="hljs-title">decltype</span><span class="hljs-params">(vec.<span class="hljs-built_in">begin</span>())</span> vectype</span>; <span class="hljs-comment">// decltype(vec.begin()) 改名为 vectype</span>

    vectype k;  <span class="hljs-comment">// 这是auto无法做到的</span>
    <span class="hljs-comment">//decltype(vec.begin()) k;  // 这是auto无法做到的</span>
    <span class="hljs-keyword">for</span> (k = vec.<span class="hljs-built_in">begin</span>(); k &lt; vec.<span class="hljs-built_in">end</span>(); k++)
    &#123;
        <span class="hljs-comment">// 做一些事情</span>
    &#125;

    <span class="hljs-keyword">enum</span> &#123;Ok, Error, Warning&#125;flag;   <span class="hljs-comment">// 匿名的枚举变量</span>
    <span class="hljs-keyword">decltype</span>(flag) tmp = Ok;

    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;</code></pre>
<h4 id="defaulted-函数"><a href="#defaulted-函数" class="headerlink" title="defaulted 函数"></a>defaulted 函数</h4><p>C++ 的类有四类特殊成员函数，它们分别是：<strong>默认构造函数、析构函数、拷贝构造函数以及拷贝赋值运算符</strong>。</p>
<p>这些类的特殊成员函数负责创建、初始化、销毁，或者拷贝类的对象。如果程序员没有显式地为一个类定义某个特殊成员函数，而又需要用到该特殊成员函数时，则编译器会隐式的为这个类生成一个默认的特殊成员函数。</p>
<pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;string&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">X</span></span>
<span class="hljs-class">&#123;</span> 
 <span class="hljs-keyword">public</span>:  
   X() = <span class="hljs-keyword">default</span>; <span class="hljs-comment">//Inline defaulted 默认构造函数</span>
   X(<span class="hljs-keyword">const</span> X&amp;); 
   X&amp; <span class="hljs-keyword">operator</span> = (<span class="hljs-keyword">const</span> X&amp;); 
   ~X() = <span class="hljs-keyword">default</span>;  <span class="hljs-comment">//Inline defaulted 析构函数</span>
 &#125;; 

 X::X(<span class="hljs-keyword">const</span> X&amp;) = <span class="hljs-keyword">default</span>;  <span class="hljs-comment">//Out-of-line defaulted 拷贝构造函数</span>
 X&amp; X::<span class="hljs-keyword">operator</span> = (<span class="hljs-keyword">const</span> X&amp;) = <span class="hljs-keyword">default</span>;     <span class="hljs-comment">//Out-of-line defaulted  拷贝赋值操作符</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Y</span>&#123;</span>&#125;;

 <span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;
 	X obj1;
 	Y obj2;
 	<span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"add defaulted functions class X: "</span> &lt;&lt; <span class="hljs-keyword">sizeof</span>(obj1) &lt;&lt; <span class="hljs-built_in">endl</span>;
 	<span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"empty class Y size: "</span> &lt;&lt; <span class="hljs-keyword">sizeof</span>(obj2) &lt;&lt; <span class="hljs-built_in">endl</span>;
 	<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
 &#125;</code></pre>
<h4 id="deleted-函数"><a href="#deleted-函数" class="headerlink" title="deleted 函数"></a>deleted 函数</h4><p>显式的禁用某个函数，C++11 标准引入了一个新特性：deleted 函数。</p>
<pre><code class="hljs C++"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">X</span></span>
<span class="hljs-class">&#123;</span>           
<span class="hljs-keyword">public</span>: 
    X(); 
    X(<span class="hljs-keyword">const</span> X&amp;) = <span class="hljs-keyword">delete</span>;  <span class="hljs-comment">// 声明拷贝构造函数为 deleted 函数</span>
    X&amp; <span class="hljs-keyword">operator</span> = (<span class="hljs-keyword">const</span> X &amp;) = <span class="hljs-keyword">delete</span>; <span class="hljs-comment">// 声明拷贝赋值操作符为 deleted 函数</span>
&#125;; 

 <span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>
<span class="hljs-function"> </span>&#123; 
      X obj1; 
      X obj2=obj1;   <span class="hljs-comment">// 错误，拷贝构造函数被禁用</span>
      X obj3; 
      obj3=obj1;     <span class="hljs-comment">// 错误，拷贝赋值操作符被禁用</span>
 &#125;</code></pre>
<h4 id="初始化"><a href="#初始化" class="headerlink" title="初始化"></a>初始化</h4><h5 id="类内成员初始化"><a href="#类内成员初始化" class="headerlink" title="类内成员初始化"></a>类内成员初始化</h5><pre><code class="hljs C++"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Mem</span></span>
<span class="hljs-class">&#123;</span>
<span class="hljs-keyword">public</span>:
    Mem(<span class="hljs-keyword">int</span> i): m(i)&#123;&#125; <span class="hljs-comment">//初始化列表给m初始化</span>
    <span class="hljs-keyword">int</span> m;
&#125;;
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Group</span></span>
<span class="hljs-class">&#123;</span>
<span class="hljs-keyword">public</span>:
    Group()&#123;&#125;

<span class="hljs-keyword">private</span>:
    <span class="hljs-keyword">int</span> data = <span class="hljs-number">1</span>;       <span class="hljs-comment">// 使用"="初始化非静态普通成员，也可以 int data&#123;1&#125;;</span>
    Mem mem&#123;<span class="hljs-number">2</span>&#125;; <span class="hljs-comment">// 对象成员，创建对象时，可以使用&#123;&#125;来调用构造函数</span>
    <span class="hljs-built_in">string</span> name&#123;<span class="hljs-string">"mike"</span>&#125;;
&#125;;</code></pre>
<h5 id="列表初始化"><a href="#列表初始化" class="headerlink" title="列表初始化"></a>列表初始化</h5><pre><code class="hljs C++"><span class="hljs-keyword">int</span> a[]&#123;<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>&#125;;
<span class="hljs-keyword">int</span> i = &#123;<span class="hljs-number">1</span>&#125;;  
<span class="hljs-keyword">int</span> j&#123;<span class="hljs-number">3</span>&#125;;</code></pre>
<h5 id="初始化结构体类型"><a href="#初始化结构体类型" class="headerlink" title="初始化结构体类型"></a>初始化结构体类型</h5><pre><code class="hljs C++"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Person</span>  </span>
<span class="hljs-class">&#123;</span>  
  <span class="hljs-built_in">std</span>::<span class="hljs-built_in">string</span> name;  
  <span class="hljs-keyword">int</span> age;  
&#125;;  

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span>  </span>
<span class="hljs-function"></span>&#123;  
    Person p = &#123;<span class="hljs-string">"Frank"</span>, <span class="hljs-number">25</span>&#125;;  
    <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span> &lt;&lt; p.name &lt;&lt; <span class="hljs-string">" : "</span> &lt;&lt; p.age &lt;&lt; <span class="hljs-built_in">std</span>::<span class="hljs-built_in">endl</span>;  
&#125;</code></pre>
<h5 id="std的初始化"><a href="#std的初始化" class="headerlink" title="std的初始化"></a>std的初始化</h5><pre><code class="hljs C++"><span class="hljs-function"><span class="hljs-built_in">std</span>::<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; <span class="hljs-title">ivec1</span><span class="hljs-params">(<span class="hljs-number">3</span>, <span class="hljs-number">5</span>)</span></span>;  
<span class="hljs-built_in">std</span>::<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; ivec2 = &#123;<span class="hljs-number">5</span>, <span class="hljs-number">5</span>, <span class="hljs-number">5</span>&#125;;  
<span class="hljs-built_in">std</span>::<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; ivec3 = &#123;<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>&#125;; <span class="hljs-comment">//不使用列表初始化用构造函数难以实现</span></code></pre>
<h5 id="防止类型收窄"><a href="#防止类型收窄" class="headerlink" title="防止类型收窄"></a>防止类型收窄</h5><pre><code class="hljs C++"><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">(<span class="hljs-keyword">void</span>)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">const</span> <span class="hljs-keyword">int</span> x = <span class="hljs-number">1024</span>;
    <span class="hljs-keyword">const</span> <span class="hljs-keyword">int</span> y = <span class="hljs-number">10</span>;

    <span class="hljs-keyword">char</span> a = x;                 <span class="hljs-comment">// 收窄，但可以通过编译</span>
    <span class="hljs-keyword">char</span>* b = <span class="hljs-keyword">new</span> <span class="hljs-keyword">char</span>(<span class="hljs-number">1024</span>);   <span class="hljs-comment">// 收窄，但可以通过编译</span>

    <span class="hljs-keyword">char</span> c = &#123; x &#125;;             <span class="hljs-comment">// err, 收窄，无法通过编译</span>
    <span class="hljs-keyword">char</span> d = &#123; y &#125;;             <span class="hljs-comment">// 可以通过编译</span>
    <span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">char</span> e&#123; <span class="hljs-number">-1</span> &#125;;      <span class="hljs-comment">// err,收窄，无法通过编译</span>

    <span class="hljs-keyword">float</span> f&#123; <span class="hljs-number">7</span> &#125;;               <span class="hljs-comment">// 可以通过编译</span>
    <span class="hljs-keyword">int</span> g&#123; <span class="hljs-number">2.0f</span> &#125;;              <span class="hljs-comment">// err,收窄，无法通过编译</span>
    <span class="hljs-keyword">float</span> * h = <span class="hljs-keyword">new</span> <span class="hljs-keyword">float</span>&#123; <span class="hljs-number">1e48</span> &#125;;  <span class="hljs-comment">// err,收窄，无法通过编译</span>
    <span class="hljs-keyword">float</span> i = <span class="hljs-number">1.2l</span>;                 <span class="hljs-comment">// 可以通过编译</span>

    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;</code></pre>
<h4 id="基于范围的for循环"><a href="#基于范围的for循环" class="headerlink" title="基于范围的for循环"></a>基于范围的for循环</h4><pre><code class="hljs C++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">int</span> a[] = &#123; <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span> &#125;;
    <span class="hljs-keyword">int</span> n = <span class="hljs-keyword">sizeof</span>(a) / <span class="hljs-keyword">sizeof</span>(*a); <span class="hljs-comment">//元素个数</span>

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; n; ++i)
    &#123;
        <span class="hljs-keyword">int</span> tmp = a[i];
        <span class="hljs-built_in">cout</span> &lt;&lt; tmp &lt;&lt; <span class="hljs-string">", "</span>;
    &#125;
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-built_in">endl</span>;

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> tmp : a)
    &#123;
        <span class="hljs-built_in">cout</span> &lt;&lt; tmp &lt;&lt; <span class="hljs-string">", "</span>;
    &#125;
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-built_in">endl</span>;

    <span class="hljs-comment">//使用引用访问元素</span>
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; n; ++i)
    &#123;
        <span class="hljs-keyword">int</span> &amp;tmp = a[i];
        tmp = <span class="hljs-number">2</span> * tmp;
        <span class="hljs-built_in">cout</span> &lt;&lt; tmp &lt;&lt; <span class="hljs-string">", "</span>;
    &#125;
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-built_in">endl</span>;

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> &amp;tmp : a)
    &#123;
        tmp = <span class="hljs-number">2</span> * tmp;
        <span class="hljs-built_in">cout</span> &lt;&lt; tmp &lt;&lt; <span class="hljs-string">", "</span>;
    &#125;
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-built_in">endl</span>;

    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;</code></pre>
<h4 id="nullptr"><a href="#nullptr" class="headerlink" title="nullptr"></a>nullptr</h4><pre><code class="hljs C++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">func</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a)</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-built_in">cout</span> &lt;&lt; __LINE__ &lt;&lt; <span class="hljs-string">" a = "</span> &lt;&lt; a &lt;&lt;<span class="hljs-built_in">endl</span>;
&#125;

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">func</span><span class="hljs-params">(<span class="hljs-keyword">int</span> *p)</span></span>
<span class="hljs-function"></span>&#123;
     <span class="hljs-built_in">cout</span> &lt;&lt; __LINE__ &lt;&lt; <span class="hljs-string">" p = "</span> &lt;&lt; p &lt;&lt;<span class="hljs-built_in">endl</span>;
&#125;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-keyword">int</span> *p1 = <span class="hljs-literal">nullptr</span>;
    <span class="hljs-keyword">int</span> *p2 = <span class="hljs-literal">NULL</span>;

    <span class="hljs-keyword">if</span>(p1 == p2)
    &#123;
        <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"equal\n"</span>;
    &#125;

    <span class="hljs-comment">//int a = nullptr; //err, 编译失败，nullptr不能转型为int</span>

    func(<span class="hljs-number">0</span>); <span class="hljs-comment">//调用func(int)， 就算写NULL，也是调用这个</span>
    func(<span class="hljs-literal">nullptr</span>);
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-keyword">sizeof</span>(<span class="hljs-literal">nullptr</span>) &lt;&lt; <span class="hljs-built_in">endl</span>;

    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;</code></pre>
<h4 id="lambda表达式"><a href="#lambda表达式" class="headerlink" title="lambda表达式"></a>lambda表达式</h4><pre><code class="hljs C++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyFunctor</span></span>
<span class="hljs-class">&#123;</span>
<span class="hljs-keyword">public</span>:
    MyFunctor(<span class="hljs-keyword">int</span> tmp) : round(tmp) &#123;&#125;
    <span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">operator</span><span class="hljs-params">()</span><span class="hljs-params">(<span class="hljs-keyword">int</span> tmp)</span> </span>&#123; <span class="hljs-keyword">return</span> tmp + round; &#125;

<span class="hljs-keyword">private</span>:
    <span class="hljs-keyword">int</span> round;
&#125;;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-comment">//仿函数</span>
    <span class="hljs-keyword">int</span> round = <span class="hljs-number">2</span>;
    <span class="hljs-function">MyFunctor <span class="hljs-title">f1</span><span class="hljs-params">(round)</span></span>;<span class="hljs-comment">//调用构造函数</span>
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"result1 = "</span> &lt;&lt; f1(<span class="hljs-number">1</span>) &lt;&lt; <span class="hljs-built_in">endl</span>; <span class="hljs-comment">//operator()(int tmp)</span>

    <span class="hljs-comment">//lambda表达式</span>
    <span class="hljs-keyword">auto</span> f2 = [=](<span class="hljs-keyword">int</span> tmp) -&gt; <span class="hljs-keyword">int</span> &#123; <span class="hljs-keyword">return</span> tmp + round; &#125; ;
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-string">"result2 = "</span> &lt;&lt; f2(<span class="hljs-number">1</span>) &lt;&lt; <span class="hljs-built_in">endl</span>;

    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;</code></pre>
<pre><code class="hljs C++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;vector&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;algorithm&gt; //std::for_each</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span>
<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> <span class="hljs-built_in">std</span>;

<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; nums;
<span class="hljs-built_in">vector</span>&lt;<span class="hljs-keyword">int</span>&gt; largeNums;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LNums</span></span>
<span class="hljs-class">&#123;</span>
<span class="hljs-keyword">public</span>:
    LNums(<span class="hljs-keyword">int</span> u): ubound(u)&#123;&#125; <span class="hljs-comment">//构造函数</span>

    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">operator</span> <span class="hljs-params">()</span> <span class="hljs-params">(<span class="hljs-keyword">int</span> i)</span> <span class="hljs-keyword">const</span></span>
<span class="hljs-function">    </span>&#123;<span class="hljs-comment">//仿函数</span>
        <span class="hljs-keyword">if</span> (i &gt; ubound)
        &#123;
            largeNums.push_back(i);
        &#125;
    &#125;
<span class="hljs-keyword">private</span>:
    <span class="hljs-keyword">int</span> ubound;
&#125;;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>
<span class="hljs-function"></span>&#123;
    <span class="hljs-comment">//初始化数据</span>
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">auto</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">10</span>; ++i)
    &#123;
        nums.push_back(i);
    &#125;
    <span class="hljs-keyword">int</span> ubound = <span class="hljs-number">5</span>;

    <span class="hljs-comment">//1、传统的for循环</span>
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">auto</span> itr = nums.<span class="hljs-built_in">begin</span>(); itr != nums.<span class="hljs-built_in">end</span>(); ++itr)
    &#123;
        <span class="hljs-keyword">if</span> (*itr &gt; ubound)
        &#123;
            largeNums.push_back(*itr);
        &#125;
    &#125;

    <span class="hljs-comment">//2、使用仿函数</span>
    for_each(nums.<span class="hljs-built_in">begin</span>(), nums.<span class="hljs-built_in">end</span>(), LNums(ubound));

    <span class="hljs-comment">//3、使用lambda函数和算法for_each</span>
    for_each(nums.<span class="hljs-built_in">begin</span>(), nums.<span class="hljs-built_in">end</span>(), [=](<span class="hljs-keyword">int</span> i)
        &#123;
            <span class="hljs-keyword">if</span> (i &gt; ubound)
            &#123;
                largeNums.push_back(i);
            &#125;
        &#125;
        );

    <span class="hljs-comment">//4、遍历元素</span>
    for_each(largeNums.<span class="hljs-built_in">begin</span>(), largeNums.<span class="hljs-built_in">end</span>(), [=](<span class="hljs-keyword">int</span> i)
        &#123;
            <span class="hljs-built_in">cout</span> &lt;&lt; i &lt;&lt; <span class="hljs-string">", "</span>;
        &#125;
        );
    <span class="hljs-built_in">cout</span> &lt;&lt; <span class="hljs-built_in">endl</span>;

    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
&#125;</code></pre>
<h4 id="线程-1"><a href="#线程-1" class="headerlink" title="线程"></a>线程</h4><h4 id="强类型枚举"><a href="#强类型枚举" class="headerlink" title="强类型枚举"></a>强类型枚举</h4><h4 id="字符串字面值"><a href="#字符串字面值" class="headerlink" title="字符串字面值"></a>字符串字面值</h4><h4 id="移动语义"><a href="#移动语义" class="headerlink" title="移动语义"></a>移动语义</h4><h4 id="可变参数模板"><a href="#可变参数模板" class="headerlink" title="可变参数模板"></a>可变参数模板</h4><h3 id="C-编译链接"><a href="#C-编译链接" class="headerlink" title="C++编译链接"></a>C++编译链接</h3><h4 id="预编译"><a href="#预编译" class="headerlink" title="预编译"></a>预编译</h4><ul>
<li><p>由源文件“.cpp/.c”生成“.i”文件，这是在预编译阶段完成的；gcc -E .cpp/.c —-&gt;.i</p>
</li>
<li><p>主要功能</p>
<ul>
<li>展开所有的宏定义，消除“#define”；</li>
<li>处理所有的预编译指令，比如#if、#ifdef等；</li>
<li>处理#include预编译指令，将包含文件插入到该预编译的位置；</li>
<li>删除所有的注释“/**/”、”//“等；</li>
<li>添加行号和文件名标识，以便于编译时编译器产生调试用的行号信息以及错误提醒；</li>
<li>保留所有的#program编译指令，原因是编译器要使用它们；</li>
</ul>
</li>
<li><p>缺点：不进行任何安全性及合法性检查</p>
</li>
</ul>
<h4 id="编译—-核心"><a href="#编译—-核心" class="headerlink" title="编译—-核心"></a>编译—-核心</h4><p>编译过程就是把经过预编译生成的文件进行一系列语法分析、词法分析、语义分析优化后生成相应的汇编代码文件。</p>
<ul>
<li><p>由“.i”文件生成“.s”文件，这是在编译阶段完成的；gcc -S .i —-&gt;.s</p>
</li>
<li><p>主要功能</p>
<ul>
<li>词法分析：将源代码文件的字符序列划分为一系列的记号，一般词法分析产生的记号有：标识符、关键字、数字、字符串、特殊符号（加号、等号）；在识别记号的同时也将标识符放好符号表、将数字、字符放入到文字表等；有一个lex程序可以实现词法扫描，会按照之前定义好的词法规则将输入的字符串分割成记号，所以编译器不需要独立的词法扫描器；</li>
<li>语法分析：语法分析器将对产生的记号进行语法分析，产生语法树——就是以表达式尾节点的树，一步步判断如何执行表达式操作。</li>
<li>语义分析：由语法阶段完成分析的并没有赋予表达式或者其他实际的意义，比如乘法、加法、减法，必须经过语义阶段才能赋予其真正的意义；语义分析主要分为静态语义和动态语义两种；静态语义通常包括声明和类型的匹配、类型的转换。比如当一个浮点型的表达式赋值给一个整型的表达式时，其中隐含了一个浮点型到整型转换的过程。只要存在类型不匹配编译器会报错。经过语义分析后的语法树的所有表达式都有了类型。动态语义分析只有在运行阶段才能确定；</li>
</ul>
</li>
</ul>
<h4 id="汇编：生成可重定位的二进制文件；（-obj文件）"><a href="#汇编：生成可重定位的二进制文件；（-obj文件）" class="headerlink" title="汇编：生成可重定位的二进制文件；（.obj文件）"></a>汇编：生成可重定位的二进制文件；（.obj文件）</h4><ul>
<li><p>由“.s”文件生成的“.obj”文件；gcc -c .s—&gt;.o;</p>
</li>
<li><p>此文件中生成符号表，能够产生符号的有：所有数据都要产生符号、指令只产生一个符号（函数名）；</p>
</li>
</ul>
<h4 id="链接"><a href="#链接" class="headerlink" title="链接"></a>链接</h4><ul>
<li><p>合并所有“.obj”文件的段并调整段偏移和段长度（按照段的属性合并，属性可以是“可读可写”、“只读”、“可读可执行”，合并后将相同属性的组织在一个页面内，比较节省空间），合并符号表，进行符号解析完成后给符号分配地址；其中符号解析的意思是：所有.obj符号表中对符号引用的地方都要找到该符号定义的地方。在编译阶段，有数据的地方都是0地址，有函数的额地方都是下一行指令的偏移量-4（由于指针是4字节）；可执行文件以页面对齐。</p>
</li>
<li><p>符号的重定位（链接核心）：将符号分配的虚拟地址写回原先未分配正确地址的地方</p>
</li>
</ul>
<h4 id="Linux下的ELF文件主要有以下四种"><a href="#Linux下的ELF文件主要有以下四种" class="headerlink" title="Linux下的ELF文件主要有以下四种"></a>Linux下的ELF文件主要有以下四种</h4><h5 id="可重定位文件-obj"><a href="#可重定位文件-obj" class="headerlink" title="可重定位文件.obj"></a>可重定位文件.obj</h5><p>这种文件包括数据和指令，可以被链接成为可执行文件（.exe）或者共享目标文件（.so），静态链接库可以归为这一类；</p>
<h5 id="可执行文件-exe"><a href="#可执行文件-exe" class="headerlink" title="可执行文件.exe"></a>可执行文件.exe</h5><p>这种文件包含了可以直接运行的程序，它的代表就是ELF可执行文件，他们一般都没有扩展名；</p>
<h5 id="共享目标文件-so"><a href="#共享目标文件-so" class="headerlink" title="共享目标文件.so"></a>共享目标文件.so</h5><p>这种文件包含了数据和指令，可以在以下两种情况下使用：一是链接器使用这种文件与其他可重定位文件和共享目标文件链接，二是动态链接器将几个共享目标文件与可执行文件结合，作为进程映像的一部分使用。</p>
<h5 id="核心转储文件"><a href="#核心转储文件" class="headerlink" title="核心转储文件"></a>核心转储文件</h5><p>当进程意外终止时，系统可以将该进程的地址空间的内容及种植的一些信息转储到核心文件中，比如core dump文件。</p>
<h3 id="数据结构"><a href="#数据结构" class="headerlink" title="数据结构"></a>数据结构</h3><p><img src="http://mi_chuan.gitee.io/blog/时间复杂度.png" srcset="/michuanblog/img/loading.gif" alt=""></p>
<p><img src="http://mi_chuan.gitee.io/blog/排序时间复杂度.png" srcset="/michuanblog/img/loading.gif" alt=""></p>
<p><img src="http://mi_chuan.gitee.io/blog/数据结构时间复杂度.png" srcset="/michuanblog/img/loading.gif" alt=""></p>
<p><img src="http://mi_chuan.gitee.io/blog/数据结构时间复杂度2.png" srcset="/michuanblog/img/loading.gif" alt=""></p>
<p><img src="http://mi_chuan.gitee.io/blog/数据结构时间复杂度3.png" srcset="/michuanblog/img/loading.gif" alt=""></p>
<h2 id="DataBase"><a href="#DataBase" class="headerlink" title="DataBase"></a>DataBase</h2><h3 id="基础"><a href="#基础" class="headerlink" title="基础"></a>基础</h3><h4 id="事务的概念和特性"><a href="#事务的概念和特性" class="headerlink" title="事务的概念和特性"></a>事务的概念和特性</h4><p>事务（Transaction）是一个操作序列，不可分割的工作单位，以BEGIN TRANSACTION开始，以ROLLBACK/COMMIT结束</p>
<p>特性：<strong>原子性</strong>、<strong>一致性</strong>、<strong>隔离性</strong>、<strong>持久性</strong></p>
<h4 id="并发一致性问题"><a href="#并发一致性问题" class="headerlink" title="并发一致性问题"></a>并发一致性问题</h4><ul>
<li><strong>丢失修改</strong>：一个事务对数据进行了修改，在事务提交之前，另一个事务对同一个数据进行了修改，覆盖了之前的修改；</li>
<li><strong>脏读</strong>（Dirty Read）：一个事务读取了被另一个事务修改、但未提交（进行了回滚）的数据，造成两个事务得到的数据不一致；</li>
<li><strong>不可重复读</strong>（Nonrepeatable Read）：在同一个事务中，某查询操作在一个时间读取某一行数据和之后一个时间读取该行数据，发现数据已经发生修改（可能被更新或删除了）；</li>
<li><strong>幻读</strong>（Phantom Read）：当同一查询多次执行时，由于其它事务在这个数据范围内执行了<strong>插入操作</strong>，会导致每次返回不同的结果集（和不可重复读的区别：针对的是一个数据整体/范围；并且需要是插入操作）</li>
</ul>
<h4 id="四种隔离级别"><a href="#四种隔离级别" class="headerlink" title="四种隔离级别"></a>四种隔离级别</h4><ul>
<li><strong>未提交读</strong>（Read Uncommited）：在一个事务提交之前，它的执行结果对其它事务也是可见的。会导致脏读、不可重复读、幻读；</li>
<li><strong>提交读</strong>（Read Commited）：一个事务只能看见已经提交的事务所作的改变。可避免脏读问题；</li>
<li><strong>可重复读</strong>（Repeatable Read）：可以确保同一个事务在多次读取同样的数据时得到相同的结果。（MySQL的默认隔离级别）。可避免不可重复读；</li>
<li><strong>可串行化</strong>（Serializable）：强制事务串行执行，使之不可能相互冲突，从而解决幻读问题。可能导致大量的超时现象和锁竞争，实际很少使用。</li>
</ul>
<h4 id="乐观锁和悲观锁"><a href="#乐观锁和悲观锁" class="headerlink" title="乐观锁和悲观锁"></a>乐观锁和悲观锁</h4><ul>
<li>悲观锁：认为数据随时会被修改，因此每次读取数据之前都会上锁，防止其它事务读取或修改数据；应用于<strong>数据更新比较频繁</strong>的场景；</li>
<li>乐观锁：操作数据时不会上锁，但是更新时会判断在此期间有没有别的事务更新这个数据，若被更新过，则失败重试；适用于读多写少的场景。乐观锁的实现方式有：<ul>
<li>加一个版本号或者时间戳字段，每次数据更新时同时更新这个字段；</li>
<li>先读取想要更新的字段或者所有字段，更新的时候比较一下，只有字段没有变化才进行更新</li>
</ul>
</li>
</ul>
<h4 id="封锁类型"><a href="#封锁类型" class="headerlink" title="封锁类型"></a>封锁类型</h4><ul>
<li><strong>排它锁</strong></li>
<li><strong>共享锁</strong></li>
<li><strong>意向锁</strong></li>
</ul>
<h4 id="MVCC-多版本并发控制"><a href="#MVCC-多版本并发控制" class="headerlink" title="MVCC(多版本并发控制)"></a>MVCC(多版本并发控制)</h4><p>MVCC在每行记录后面都保存有两个隐藏的列，用来存储<strong>创建版本号</strong>和<strong>删除版本号</strong>。</p>
<ul>
<li>创建版本号：创建一个数据行时的事务版本号（<strong>事务版本号</strong>：事务开始时的系统版本号；系统版本号：每开始一个新的事务，系统版本号就会自动递增）；</li>
<li>删除版本号：删除操作时的事务版本号；</li>
<li>各种操作：<ul>
<li>插入操作时，记录创建版本号；</li>
<li>删除操作时，记录删除版本号；</li>
<li>更新操作时，先记录删除版本号，再新增一行记录创建版本号；</li>
<li>查询操作时，要符合以下条件才能被查询出来：删除版本号未定义或大于当前事务版本号（删除操作是在当前事务启动之后做的）；创建版本号小于或等于当前事务版本号（创建操作是事务完成或者在事务启动之前完成）</li>
</ul>
</li>
</ul>
<p>通过版本号减少了锁的争用，<strong>提高了系统性能</strong>；可以实现<strong>提交读</strong>和<strong>可重复读</strong>两种隔离级别，未提交读无需使用MVCC</p>
<h4 id="表连接"><a href="#表连接" class="headerlink" title="表连接"></a>表连接</h4><ul>
<li>内连接（Inner Join）：仅将两个表中满足连接条件的行组合起来作为结果集<ul>
<li>自然连接：只考虑属性相同的元组对；</li>
<li>等值连接：给定条件进行查询</li>
</ul>
</li>
<li>外连接（Outer Join）<ul>
<li>左连接：左边表的所有数据都有显示出来，右边的表数据只显示共同有的那部分，没有对应的部分补NULL；</li>
<li>右连接：和左连接相反；</li>
<li>全外连接（Full Outer Join）：查询出左表和右表所有数据，但是去除两表的重复数据</li>
</ul>
</li>
<li>交叉连接（Cross Join）：返回两表的笛卡尔积（对于所含数据分别为m、n的表，返回m*n的结果）</li>
</ul>
<h4 id="触发器"><a href="#触发器" class="headerlink" title="触发器"></a>触发器</h4><p>由事件（比如INSERT/UPDATE/DELETE）来触发运行的操作（不能被直接调用，不能接收参数）。在数据库里以独立的对象存储，用于<strong>保证数据完整性</strong>（比如可以检验或转换数据）。</p>
<h4 id="约束类型"><a href="#约束类型" class="headerlink" title="约束类型"></a>约束类型</h4><ul>
<li>主键约束（Primary Key）</li>
<li>唯一约束（Unique）</li>
<li>检查约束（check）</li>
<li>非空约束(NOT NULL)</li>
<li>外键约束（Foreign Key）</li>
<li>默认值约束(Default)</li>
</ul>
<h4 id="视图"><a href="#视图" class="headerlink" title="视图"></a>视图</h4><p>从数据库的基本表中通过查询选取出来的数据组成的<strong>虚拟表</strong>（数据库中存放视图的定义）。可以对其进行增/删/改/查等操作。视图是对若干张基本表的引用，一张虚表，查询语句执行的结果，不存储具体的数据（基本表数据发生了改变，视图也会跟着改变）；可以跟基本表一样，进行增删改查操作(ps:增删改操作有条件限制)；如连表查询产生的视图无法进行，对视图的增删改会影响原表的数据。</p>
<ul>
<li>通过只给用户访问视图的权限，保证数据的<strong>安全性</strong>；</li>
<li><strong>简化</strong>复杂的SQL操作，隐藏数据的复杂性（比如复杂的连接）；</li>
</ul>
<h4 id="游标"><a href="#游标" class="headerlink" title="游标"></a>游标</h4><p>用于定位在查询返回的<strong>结果集的特定行</strong>，以对特定行进行操作。使用游标可以方便地对结果集进行移动遍历，根据需要滚动或对浏览/修改任意行中的数据。主要用于交互式应用。</p>
<h4 id="数据库索引的实现原理"><a href="#数据库索引的实现原理" class="headerlink" title="数据库索引的实现原理"></a>数据库索引的实现原理</h4><h5 id="使用B树和B-树的比较"><a href="#使用B树和B-树的比较" class="headerlink" title="使用B树和B+树的比较"></a>使用B树和B+树的比较</h5><p>InnoDB的索引使用的是B+树实现，B+树对比B树的好处：</p>
<ul>
<li>IO次数少：B+树的中间结点只存放索引，数据都存在叶结点中，因此中间结点可以存更多的数据，让索引树更加矮胖；</li>
<li>范围查询效率更高：B树需要中序遍历整个树，只B+树需要遍历叶结点中的链表；</li>
<li>查询效率更加稳定：每次查询都需要从根结点到叶结点，路径长度相同，所以每次查询的效率都差不多</li>
</ul>
<h5 id="使用B树索引和哈希索引的比较"><a href="#使用B树索引和哈希索引的比较" class="headerlink" title="使用B树索引和哈希索引的比较"></a>使用B树索引和哈希索引的比较</h5><p>哈希索引能以 O(1) 时间进行查找，但是只支持精确查找，无法用于部分查找和范围查找，无法用于排序与分组；B树索引支持大于小于等于查找，范围查找。哈希索引遇到大量哈希值相等的情况后查找效率会降低。哈希索引不支持数据的排序。</p>
<h4 id="索引的优缺点"><a href="#索引的优缺点" class="headerlink" title="索引的优缺点"></a>索引的优缺点</h4><ul>
<li>大大加快了数据的<strong>检索速度</strong>；</li>
<li>可以显著减少查询中<strong>分组和排序</strong>的时间；</li>
<li>通过创建唯一性索引，可以保证数据库表中每一行数据的唯一性；</li>
<li>将随机 I/O 变为<strong>顺序 I/O</strong>（B+Tree 索引是有序的，会将相邻的数据都存储在一起）</li>
</ul>
<p>缺点：建立和维护索引耗费时间空间，更新索引很慢。</p>
<h4 id="创建索引"><a href="#创建索引" class="headerlink" title="创建索引"></a>创建索引</h4><ul>
<li>某列经常作为最大最小值；</li>
<li>经常被查询的字段；</li>
<li>经常用作表连接的字段；</li>
<li>经常出现在ORDER BY/GROUP BY/DISDINCT后面的字段</li>
</ul>
<h3 id="SQL"><a href="#SQL" class="headerlink" title="SQL"></a>SQL</h3><h4 id="语法"><a href="#语法" class="headerlink" title="语法"></a>语法</h4><h5 id="SELECT语句"><a href="#SELECT语句" class="headerlink" title="SELECT语句"></a>SELECT语句</h5><pre><code class="hljs sql"><span class="hljs-keyword">SELECT</span> column_name(s) <span class="hljs-keyword">FROM</span> table_name</code></pre>
<h5 id="SELECT语句和WHERE子句"><a href="#SELECT语句和WHERE子句" class="headerlink" title="SELECT语句和WHERE子句"></a>SELECT语句和WHERE子句</h5><pre><code class="hljs sql"><span class="hljs-keyword">SELECT</span> [*] <span class="hljs-keyword">FROM</span> [TableName] <span class="hljs-keyword">WHERE</span> [condition1]</code></pre>
<h5 id="SELECT语句与WHERE和-或子句"><a href="#SELECT语句与WHERE和-或子句" class="headerlink" title="SELECT语句与WHERE和/或子句"></a>SELECT语句与WHERE和/或子句</h5><pre><code class="hljs sql"><span class="hljs-keyword">SELECT</span> [*] <span class="hljs-keyword">FROM</span> [TableName] <span class="hljs-keyword">WHERE</span> [condition1] [<span class="hljs-keyword">AND</span> [<span class="hljs-keyword">OR</span>]] [condition2]...</code></pre>
<h5 id="SELECT语句与ORDER-BY"><a href="#SELECT语句与ORDER-BY" class="headerlink" title="SELECT语句与ORDER BY"></a>SELECT语句与ORDER BY</h5><pre><code class="hljs sql"><span class="hljs-keyword">SELECT</span> column_name()
<span class="hljs-keyword">FROM</span> table_name
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> column_name() <span class="hljs-keyword">ASC</span> <span class="hljs-keyword">or</span> <span class="hljs-keyword">DESC</span></code></pre>
<h5 id="SELECT-DISTINCT-区分-子句"><a href="#SELECT-DISTINCT-区分-子句" class="headerlink" title="SELECT DISTINCT(区分)子句"></a>SELECT DISTINCT(区分)子句</h5><pre><code class="hljs n1ql"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">DISTINCT</span> column1, column2....columnN
<span class="hljs-keyword">FROM</span>   table_name;</code></pre>
<h5 id="SELECT-IN子句"><a href="#SELECT-IN子句" class="headerlink" title="SELECT IN子句"></a>SELECT IN子句</h5><pre><code class="hljs sql"><span class="hljs-keyword">SELECT</span> column1, column2....columnN
<span class="hljs-keyword">FROM</span>   table_name
<span class="hljs-keyword">WHERE</span>  column_name <span class="hljs-keyword">IN</span> (val<span class="hljs-number">-1</span>, val<span class="hljs-number">-2</span>,...val-N);</code></pre>
<h5 id="SELECT-LIKE-类-子句"><a href="#SELECT-LIKE-类-子句" class="headerlink" title="SELECT LIKE (类)子句"></a>SELECT LIKE (类)子句</h5><pre><code class="hljs sql"><span class="hljs-keyword">SELECT</span> column1, column2....columnN
<span class="hljs-keyword">FROM</span>   table_name
<span class="hljs-keyword">WHERE</span>  column_name <span class="hljs-keyword">LIKE</span> &#123; PATTERN &#125;;</code></pre>
<h5 id="SELECT-COUNT-计数-子句"><a href="#SELECT-COUNT-计数-子句" class="headerlink" title="SELECT COUNT(计数)子句"></a>SELECT COUNT(计数)子句</h5><pre><code class="hljs sql"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">COUNT</span>(column_name)
<span class="hljs-keyword">FROM</span>   table_name
<span class="hljs-keyword">WHERE</span>  CONDITION;</code></pre>
<h5 id="SELECT与HAVING子句"><a href="#SELECT与HAVING子句" class="headerlink" title="SELECT与HAVING子句"></a>SELECT与HAVING子句</h5><pre><code class="hljs sql"><span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">SUM</span>(column_name)
<span class="hljs-keyword">FROM</span>   table_name
<span class="hljs-keyword">WHERE</span>  CONDITION
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> column_name
<span class="hljs-keyword">HAVING</span> (arithematic <span class="hljs-keyword">function</span> condition);</code></pre>
<h5 id="INSERT-INTO语句"><a href="#INSERT-INTO语句" class="headerlink" title="INSERT INTO语句"></a>INSERT INTO语句</h5><pre><code class="hljs sql"><span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> table_name (<span class="hljs-keyword">column</span>, column1, column2, column3, ...)
<span class="hljs-keyword">VALUES</span> (<span class="hljs-keyword">value</span>, value1, value2, value3 ...)</code></pre>
<h5 id="UPDATE语句"><a href="#UPDATE语句" class="headerlink" title="UPDATE语句"></a>UPDATE语句</h5><pre><code class="hljs sql"><span class="hljs-keyword">UPDATE</span> table_name
<span class="hljs-keyword">SET</span> <span class="hljs-keyword">column</span>=<span class="hljs-keyword">value</span>, column1=value1,...
<span class="hljs-keyword">WHERE</span> someColumn=someValue</code></pre>
<h5 id="DELETE语句"><a href="#DELETE语句" class="headerlink" title="DELETE语句"></a>DELETE语句</h5><pre><code class="hljs sql"><span class="hljs-keyword">DELETE</span> <span class="hljs-keyword">FROM</span> tableName
<span class="hljs-keyword">WHERE</span> someColumn = someValue</code></pre>
<h5 id="CREATE-语句"><a href="#CREATE-语句" class="headerlink" title="CREATE 语句"></a>CREATE 语句</h5><pre><code class="hljs sql"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> table_name(
column1 datatype,
column2 datatype,
column3 datatype,
.....
columnN datatype,
PRIMARY <span class="hljs-keyword">KEY</span>( one <span class="hljs-keyword">or</span> more <span class="hljs-keyword">columns</span> )
);</code></pre>
<h5 id="DROP-语句"><a href="#DROP-语句" class="headerlink" title="DROP 语句"></a>DROP 语句</h5><pre><code class="hljs sql"><span class="hljs-keyword">DROP</span> <span class="hljs-keyword">TABLE</span> table_name;</code></pre>
<h5 id="CREATE-INDEX语句"><a href="#CREATE-INDEX语句" class="headerlink" title="CREATE INDEX语句"></a>CREATE INDEX语句</h5><pre><code class="hljs sql"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">UNIQUE</span> <span class="hljs-keyword">INDEX</span> index_name
<span class="hljs-keyword">ON</span> table_name ( column1, column2,...columnN);</code></pre>
<h5 id="DROP-INDEX语句"><a href="#DROP-INDEX语句" class="headerlink" title="DROP INDEX语句"></a>DROP INDEX语句</h5><pre><code class="hljs sql"><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> table_name
<span class="hljs-keyword">DROP</span> <span class="hljs-keyword">INDEX</span> index_name;</code></pre>
<h5 id="DESC语句"><a href="#DESC语句" class="headerlink" title="DESC语句"></a>DESC语句</h5><pre><code class="hljs sql">DESC table_name;</code></pre>
<h5 id="TRUNCATE-截断表语句"><a href="#TRUNCATE-截断表语句" class="headerlink" title="TRUNCATE 截断表语句"></a>TRUNCATE 截断表语句</h5><pre><code class="hljs sql"><span class="hljs-keyword">TRUNCATE</span> <span class="hljs-keyword">TABLE</span> table_name;</code></pre>
<h5 id="ALTER-TABLE语句"><a href="#ALTER-TABLE语句" class="headerlink" title="ALTER TABLE语句"></a>ALTER TABLE语句</h5><pre><code class="hljs sql"><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> table_name &#123;<span class="hljs-keyword">ADD</span>|<span class="hljs-keyword">DROP</span>|<span class="hljs-keyword">MODIFY</span>&#125; column_name &#123;data_ype&#125;;</code></pre>
<h5 id="ALTER-TABLE语句-对表名重命名"><a href="#ALTER-TABLE语句-对表名重命名" class="headerlink" title="ALTER TABLE语句(对表名重命名)"></a>ALTER TABLE语句(对表名重命名)</h5><pre><code class="hljs sql"><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">TABLE</span> table_name <span class="hljs-keyword">RENAME</span> <span class="hljs-keyword">TO</span> new_table_name;</code></pre>
<h5 id="Use语句"><a href="#Use语句" class="headerlink" title="Use语句"></a>Use语句</h5><pre><code class="hljs sql"><span class="hljs-keyword">USE</span> database_name;</code></pre>
<h5 id="COMMIT语句"><a href="#COMMIT语句" class="headerlink" title="COMMIT语句"></a>COMMIT语句</h5><pre><code class="hljs sql"><span class="hljs-keyword">COMMIT</span>;</code></pre>
<h5 id="ROLLBACK语句"><a href="#ROLLBACK语句" class="headerlink" title="ROLLBACK语句"></a>ROLLBACK语句</h5><pre><code class="hljs sql"><span class="hljs-keyword">ROLLBACK</span>;</code></pre>
<h5 id="MySQL-LIMIT语法"><a href="#MySQL-LIMIT语法" class="headerlink" title="MySQL LIMIT语法"></a>MySQL LIMIT语法</h5><pre><code class="hljs sql"><span class="hljs-keyword">SELECT</span> column_name(s)
<span class="hljs-keyword">FROM</span> table_name
<span class="hljs-keyword">WHERE</span> condition
<span class="hljs-keyword">LIMIT</span> &lt;M&gt; <span class="hljs-keyword">OFFSET</span> &lt;N&gt;;</code></pre>
<h3 id="MySQL"><a href="#MySQL" class="headerlink" title="MySQL"></a>MySQL</h3><h4 id="Effective-MySQL"><a href="#Effective-MySQL" class="headerlink" title="Effective MySQL"></a>Effective MySQL</h4><p><img src="http://mi_chuan.gitee.io/blog/Effective MySQL.png" srcset="/michuanblog/img/loading.gif" alt="Effective MySQL"></p>
<h4 id="高性能MySQL"><a href="#高性能MySQL" class="headerlink" title="高性能MySQL"></a>高性能MySQL</h4><p><img src="http://mi_chuan.gitee.io/blog/高性能MySQL.png" srcset="/michuanblog/img/loading.gif" alt="高性能MySQL"></p>
<h4 id="InnoDB存储引擎"><a href="#InnoDB存储引擎" class="headerlink" title="InnoDB存储引擎"></a>InnoDB存储引擎</h4><p><img src="http://mi_chuan.gitee.io/blog/InnoDB存储引擎.png" srcset="/michuanblog/img/loading.gif" alt="InnoDB存储引擎"></p>
<h2 id="参考文献"><a href="#参考文献" class="headerlink" title="参考文献"></a>参考文献</h2><h3 id="网址"><a href="#网址" class="headerlink" title="网址"></a>网址</h3><p><a href="https://github.com/wolverinn/Waking-Up" target="_blank" rel="noopener">计算机基础知识</a></p>
<p><a href="https://www.runoob.com/linux/linux-tutorial.html" target="_blank" rel="noopener">Linux教程</a></p>
<h3 id="C-1"><a href="#C-1" class="headerlink" title="C++"></a>C++</h3><p><a href="https://blog.csdn.net/tennysonsky/article/details/77817048" target="_blank" rel="noopener">C++11新特性学习</a></p>
<p>《深入理解C++11》</p>
<p>《Effective STL》</p>
<p>《C Primer Plus》</p>
<p>《深度探索C++对象模型》</p>
<p>《Effective C++》</p>
<h3 id="OS"><a href="#OS" class="headerlink" title="OS"></a>OS</h3><p>《精通Linux》</p>
<p>《Unix系统调用》</p>
<p>《Linux命令行与shell脚本编程大全》</p>
<p>《Linux+Shell脚本攻略》</p>
<p>《数据结构(C++语言版)》</p>
<p>《现代操作系统》</p>
<h3 id="Computer-Network"><a href="#Computer-Network" class="headerlink" title="Computer Network"></a>Computer Network</h3><p>《计算机网络:自顶向下方法》</p>
<h3 id="DataBase-1"><a href="#DataBase-1" class="headerlink" title="DataBase"></a>DataBase</h3><p>《Effective MySQL》</p>
<p>《高性能MySQL》</p>
<p>《InnoDB存储引擎》</p>

            </article>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                  <div class="post-meta mr-3">
                    <i class="iconfont icon-category"></i>
                    
                      <a class="hover-with-bg" href="/michuanblog/categories/%E9%9D%A2%E8%AF%95/">面试</a>
                    
                  </div>
                
                
                  <div class="post-meta">
                    <i class="iconfont icon-tags"></i>
                    
                      <a class="hover-with-bg" href="/michuanblog/tags/%E9%9D%A2%E8%AF%95/">面试</a>
                    
                      <a class="hover-with-bg" href="/michuanblog/tags/MySQL/">MySQL</a>
                    
                      <a class="hover-with-bg" href="/michuanblog/tags/%E6%95%B0%E6%8D%AE%E5%BA%93/">数据库</a>
                    
                      <a class="hover-with-bg" href="/michuanblog/tags/C/">C++</a>
                    
                      <a class="hover-with-bg" href="/michuanblog/tags/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/">操作系统</a>
                    
                      <a class="hover-with-bg" href="/michuanblog/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/">计算机网络</a>
                    
                  </div>
                
              </div>
              
                <p class="note note-warning">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-sa/4.0/deed.zh" target="_blank" rel="nofollow noopener noopener">CC BY-SA 4.0 协议</a> ，转载请注明出处！</p>
              
              
                <div class="post-prevnext row">
                  <div class="post-prev col-6">
                    
                    
                      <a href="/michuanblog/2020/08/14/50%E9%81%93SQL%E6%9F%A5%E8%AF%A2%E8%AF%AD%E5%8F%A5%E7%BB%83%E4%B9%A0/">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">50道SQL查询语句练习</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </div>
                  <div class="post-next col-6">
                    
                    
                      <a href="/michuanblog/2020/08/08/lcof-content/">
                        <span class="hidden-mobile">lcof_content</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </div>
                </div>
              
            </div>

            
              <!-- Comments -->
              <div class="comments" id="comments">
                
                
  <div id="vcomments"></div>
  <script type="text/javascript">
    function loadValine() {
      addScript('https://cdn.staticfile.org/valine/1.4.14/Valine.min.js', function () {
        new Valine({
          el: "#vcomments",
          app_id: "tKy1BysLG32PuX7L8s0rQi9C-gzGzoHsz",
          app_key: "wlDiPjGWwM0U49QD4CpxH5dz",
          placeholder: "说点什么",
          path: window.location.pathname,
          avatar: "retro",
          meta: ["nick","mail","link"],
          pageSize: "10",
          lang: "zh-CN",
          highlight: false,
          recordIP: false,
          serverURLs: "",
        });
      });
    }
    createObserver(loadValine, 'vcomments');
  </script>
  <noscript>Please enable JavaScript to view the <a href="https://valine.js.org" target="_blank" rel="nofollow noopener noopener">comments
      powered by Valine.</a></noscript>


              </div>
            
          </div>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div id="tocbot"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    
  </main>

  
    <a id="scroll-top-button" href="#" role="button">
      <i class="iconfont icon-arrowup" aria-hidden="true"></i>
    </a>
  

  
    <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
  

  
    <!-- APlayer 音乐播放器 -->
    <div id="aplayer"></div>
    <script defer src="https://cdn.staticfile.org/aplayer/1.10.1/APlayer.min.js" ></script>
<link  rel="stylesheet" href="https://cdn.staticfile.org/aplayer/1.10.1/APlayer.min.css" />
<script type="text/javascript">
  var oldLoadAp = window.onload;
  window.onload = function () {
    oldLoadAp && oldLoadAp();

    new APlayer({
      container: document.getElementById('aplayer'),
      fixed: true,
      autoplay: 'false' === 'true',
      loop: 'all',
      order: 'random',
      theme: '#b7daff',
      preload: 'none',
      audio: [{"name":"黄杨扁担","artist":"鹿女王","url":"http://mi_chuan.gitee.io/blog/黄杨扁担.mp3","cover":"http://mi_chuan.gitee.io/blog/黄杨扁担.png"},{"name":"隔世信","artist":"以冬","url":"http://mi_chuan.gitee.io/blog/隔世信.mp3","cover":"http://mi_chuan.gitee.io/blog/隔世信.jpg"}]
    });
  }
</script>

  

  

  <footer class="mt-5">
  <div class="text-center py-3">
    <div>
      <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a>
      <i class="iconfont icon-love"></i>
      <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener">
        <span>Fluid</span></a>
    </div>
    

    

    
  </div>
</footer>

<!-- SCRIPTS -->
<script  src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js" ></script>
<script  src="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/js/bootstrap.min.js" ></script>
<script  src="/michuanblog/js/debouncer.js" ></script>
<script  src="/michuanblog/js/main.js" ></script>

<!-- Plugins -->


  
    <script  src="/michuanblog/js/lazyload.js" ></script>
  



  <script defer src="https://cdn.staticfile.org/clipboard.js/2.0.6/clipboard.min.js" ></script>
  <script  src="/michuanblog/js/clipboard-use.js" ></script>







  <script  src="https://cdn.staticfile.org/tocbot/4.11.1/tocbot.min.js" ></script>
  <script>
    $(document).ready(function () {
      var boardCtn = $('#board-ctn');
      var boardTop = boardCtn.offset().top;

      tocbot.init({
        tocSelector: '#tocbot',
        contentSelector: 'article.markdown-body',
        headingSelector: 'h1,h2,h3,h4,h5,h6',
        linkClass: 'tocbot-link',
        activeLinkClass: 'tocbot-active-link',
        listClass: 'tocbot-list',
        isCollapsedClass: 'tocbot-is-collapsed',
        collapsibleClass: 'tocbot-is-collapsible',
        collapseDepth: 0,
        scrollSmooth: true,
        headingsOffset: -boardTop
      });
      if ($('.toc-list-item').length > 0) {
        $('#toc').css('visibility', 'visible');
      }
    });
  </script>



  <script  src="https://cdn.staticfile.org/typed.js/2.0.11/typed.min.js" ></script>
  <script>
    var typed = new Typed('#subtitle', {
      strings: [
        '  ',
        "面试基础知识&nbsp;",
      ],
      cursorChar: "_",
      typeSpeed: 70,
      loop: false,
    });
    typed.stop();
    $(document).ready(function () {
      $(".typed-cursor").addClass("h2");
      typed.start();
    });
  </script>



  <script  src="https://cdn.staticfile.org/anchor-js/4.2.2/anchor.min.js" ></script>
  <script>
    anchors.options = {
      placement: "right",
      visible: "hover",
      
    };
    var el = "h1,h2,h3,h4,h5,h6".split(",");
    var res = [];
    for (item of el) {
      res.push(".markdown-body > " + item)
    }
    anchors.add(res.join(", "))
  </script>



  <script  src="/michuanblog/js/local-search.js" ></script>
  <script>
    var path = "/michuanblog/local-search.xml";
    var inputArea = document.querySelector("#local-search-input");
    inputArea.onclick = function () {
      searchFunc(path, 'local-search-input', 'local-search-result');
      this.onclick = null
    }
  </script>



  <script  src="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.css" />

  <script>
    $('#post img:not(.no-zoom img, img[no-zoom]), img[zoom]').each(
      function () {
        var element = document.createElement('a');
        $(element).attr('data-fancybox', 'images');
        $(element).attr('href', $(this).attr('src'));
        $(this).wrap(element);
      }
    );
  </script>





  

  
    <!-- MathJax -->
    <script>
      MathJax = {
        tex: {
          inlineMath: [['$', '$'], ['\\(', '\\)']]
        },
        options: {
          renderActions: {
            findScript: [10, doc => {
              document.querySelectorAll('script[type^="math/tex"]').forEach(node => {
                const display = !!node.type.match(/; *mode=display/);
                const math = new doc.options.MathItem(node.textContent, doc.inputJax[0], display);
                const text = document.createTextNode('');
                node.parentNode.replaceChild(text, node);
                math.start = { node: text, delim: '', n: 0 };
                math.end = { node: text, delim: '', n: 0 };
                doc.math.push(math);
              });
            }, '', false],
            insertedScript: [200, () => {
              document.querySelectorAll('mjx-container').forEach(node => {
                let target = node.parentNode;
                if (target.nodeName.toLowerCase() === 'li') {
                  target.parentNode.classList.add('has-jax');
                }
              });
            }, '', false]
          }
        }
      };
    </script>

    <script async src="https://cdn.staticfile.org/mathjax/3.0.5/es5/tex-svg.js" ></script>

  



  
  
    <script>
      !function (e, t, a) {
        function r() {
          for (var e = 0; e < s.length; e++) s[e].alpha <= 0 ? (t.body.removeChild(s[e].el), s.splice(e, 1)) : (s[e].y--, s[e].scale += .004, s[e].alpha -= .013, s[e].el.style.cssText = "left:" + s[e].x + "px;top:" + s[e].y + "px;opacity:" + s[e].alpha + ";transform:scale(" + s[e].scale + "," + s[e].scale + ") rotate(45deg);background:" + s[e].color + ";z-index:99999");
          requestAnimationFrame(r)
        }

        function n() {
          var t = "function" == typeof e.onclick && e.onclick;
          e.onclick = function (e) {
            t && t(), o(e)
          }
        }

        function o(e) {
          var a = t.createElement("div");
          a.className = "heart", s.push({
            el: a,
            x: e.clientX - 5,
            y: e.clientY - 5,
            scale: 1,
            alpha: 1,
            color: c()
          }), t.body.appendChild(a)
        }

        function i(e) {
          var a = t.createElement("style");
          a.type = "text/css";
          try {
            a.appendChild(t.createTextNode(e))
          } catch (t) {
            a.styleSheet.cssText = e
          }
          t.getElementsByTagName("head")[0].appendChild(a)
        }

        function c() {
          return "rgb(" + ~~(255 * Math.random()) + "," + ~~(255 * Math.random()) + "," + ~~(255 * Math.random()) + ")"
        }

        var s = [];
        e.requestAnimationFrame = e.requestAnimationFrame || e.webkitRequestAnimationFrame || e.mozRequestAnimationFrame || e.oRequestAnimationFrame || e.msRequestAnimationFrame || function (e) {
          setTimeout(e, 1e3 / 60)
        }, i(".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"), n(), r()
      }(window, document);
    </script>
  








  <script  src="https://cdn.staticfile.org/mermaid/8.5.0/mermaid.min.js" ></script>
  <script>
    if (window.mermaid) {
      mermaid.initialize({"theme":"default"});
    }
  </script>







<script src="/michuanblog/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"log":false,"pluginJsPath":"lib/","pluginModelPath":"assets/","pluginRootPath":"live2dw/","tagMode":false});</script></body>
</html>
